美文网首页
JVM 出现 fullGC 很频繁,怎么去线上排查问题

JVM 出现 fullGC 很频繁,怎么去线上排查问题

作者: 青城楼主 | 来源:发表于2018-07-31 07:33 被阅读2306次

Full GC的原因

我们知道Full GC的触发条件大致情况有以下几种情况:

  1. 程序执行了System.gc() //建议jvm执行fullgc,并不一定会执行
  2. 执行了jmap -histo:live pid命令 //这个会立即触发fullgc
  3. 在执行minor gc的时候进行的一系列检查

执行Minor GC的时候,JVM会检查老年代中最大连续可用空间是否大于了当前新生代所有对象的总大小。
如果大于,则直接执行Minor GC(这个时候执行是没有风险的)。
如果小于了,JVM会检查是否开启了空间分配担保机制,如果没有开启则直接改为执行Full GC。
如果开启了,则JVM会检查老年代中最大连续可用空间是否大于了历次晋升到老年代中的平均大小,如果小于则执行改为执行Full GC。
如果大于则会执行Minor GC,如果Minor GC执行失败则会执行Full GC

对于我们的情况,可以初步排除1,2两种情况,最有可能是4和5这两种情况。为了进一步排查原因,我们在线上开启了 -XX:+HeapDumpBeforeFullGC。

注意:
JVM在执行dump操作的时候是会发生stop the word事件的,也就是说此时所有的用户线程都会暂停运行。
为了在此期间也能对外正常提供服务,建议采用分布式部署,并采用合适的负载均衡算法

JVM参数的设置:

线上这个dubbo服务是分布式部署,在其中一台机子上开启了 -XX:HeapDumpBeforeFullGC,总体JVM参数如下:

-Xmx2g
-XX:+HeapDumpBeforeFullGC
-XX:HeapDumpPath=.
-Xloggc:gc.log
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100m
-XX:HeapDumpOnOutOfMemoryError

Dump文件分析

dump下来的文件大约1.8g,用jvisualvm查看,发现用char[]类型的数据占用了41%内存,同时另外一个com.alibaba.druid.stat.JdbcSqlStat类型的数据占用了35%的内存,也就是说整个堆中几乎全是这两类数据。如下图:


image.png

查看char[]类型数据,发现几乎全是sql语句。


image.png
接下来查看char[]的引用情况:
image.png

找到了JdbcSqlStat类,在代码中查看这个类的代码,关键代码如下:
//构造函数只有这一个
public JdbcSqlStat(String sql){
this.sql = sql;
this.id = DruidDriver.createSqlStatId();
}

//查看这个函数的调用情况,找到com.alibaba.druid.stat.JdbcDataSourceStat#createSqlStat方法:

public JdbcSqlStat createSqlStat(String sql) {
lock.writeLock().lock();
try {
JdbcSqlStat sqlStat = sqlStatMap.get(sql);
if (sqlStat == null) {
sqlStat = new JdbcSqlStat(sql);
sqlStat.setDbType(this.dbType);
sqlStat.setName(this.name);
sqlStatMap.put(sql, sqlStat);
}

    return sqlStat;
} finally {
    lock.writeLock().unlock();
}

}

//这里用了一个map来存放所有的sql语句。

其实到这里也就知道什么原因造成了这个问题,因为我们使用的数据源是阿里巴巴的druid,这个druid提供了一个sql语句监控功能,同时我们也开启了这个功能。只需要在配置文件中把这个功能关掉应该就能消除这个问题,事实也的确如此,关掉这个功能后到目前为止线上没再触发FullGC


image.png

其他

如果用mat工具查看,建议把 “Keep unreachable objects” 勾上,否则mat会把堆中不可达的对象去除掉,这样我们的分析也许会变得没有意义。如下图:Window–>References 。另外jvisualvm对ool的支持不是很好,如果需要oql建议使用mat。


image.png

转自https://blog.csdn.net/wilsonpeng3/article/details/70064336

相关文章

  • JVM 出现 fullGC 很频繁,怎么去线上排查问题

    Full GC的原因 我们知道Full GC的触发条件大致情况有以下几种情况: 程序执行了System.gc() ...

  • 线上GC异常排查

    线上GC异常排查 1.现象 最近去线上看了下gc情况,发现出现频繁的fullGC。问题如下图: 然后查看了下GC原...

  • CMS堆外内存泄露案例2

    问题描述 线上生产机器fullgc很频繁几乎一分钟一次,younggc确无。 问题分析 fullgc频繁第一反应是...

  • 线上FullGC频繁的排查

    问题 前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC。 Full...

  • 频繁FullGC怎么排查?

    这种问题最好的办法就是结合有具体的例⼦举例分析,如果没有就说⼀般的分析步骤。发⽣FGC有可能是内存分配不合理,⽐如...

  • JVM 调优实战

    简书 许乐转载请注明原创出处,谢谢! 【案例】 最近我的同学遇到一个线上问题,线上机器的jvm进程频繁FullGC...

  • Day15 JVM调优实战

    JVM调优 主要调这几个指标,GC停顿时间,吞吐量,FullGC次数。 当我们发现线上出现频繁的gc的时候,不能直...

  • Day16 JVM调优实战

    JVM调优 主要调这几个指标,GC停顿时间,吞吐量,FullGC次数。 当我们发现线上出现频繁的gc的时候,不能直...

  • JVM调优-转载

    【案例】 最近我的同学遇到一个线上问题,线上机器的jvm进程频繁FullGC(大约每10分钟一次),登陆机器发现j...

  • Java应用内存泄露排查

    JVM如果出现内存泄露,典型的现象就是系统FullGC比较频繁。到最后干脆OOM(Out of Memory)了。...

网友评论

      本文标题:JVM 出现 fullGC 很频繁,怎么去线上排查问题

      本文链接:https://www.haomeiwen.com/subject/ahsfvftx.html