博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线上FullGC频繁的排查
阅读量:6908 次
发布时间:2019-06-27

本文共 2119 字,大约阅读时间需要 7 分钟。

线上FullGC频繁的排查

问题

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

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. 在程序中长期持有了对象的引用 //对象年龄达到指定阈值也会进入老年代

对于我们的情况,可以初步排除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%的内存,也就是说整个堆中几乎全是这两类数据。如下图:

a

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

b

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

c

找到了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

d

其他

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

image

转载地址:http://fdwcl.baihongyu.com/

你可能感兴趣的文章
ICMP报文 (1)
查看>>
JAVA array,map 转 json 字符串
查看>>
Apache Flink,如何重新定义计算?
查看>>
微软 Azure 容器服务要关停,你想好怎么迁移了吗?
查看>>
ROG全球行销总监尤彦博:强劲超薄的GX501与中国电竞产业
查看>>
开发者是保护代码道德的最后防线?
查看>>
阿里云跻身Gartner魔力象限,引外媒纷纷点赞
查看>>
苹果也得为它打工 iPhoneX大卖 它将入账143亿美元
查看>>
金立S10“又”入围吉林6月畅销手机排行榜,短时间内连下五省!
查看>>
375万买垃圾房,爆改后变千万豪宅,你也能做到
查看>>
沈颖刚:生物柴油或是高原柴油货车污染治理有效途径
查看>>
掌阅公布数字阅读报告:00后成第二大阅读群体
查看>>
冬季风暴席卷美国致航班取消车祸频发 20万人断电
查看>>
民航局正式启动北斗星基增强系统民航应用验证评估工作
查看>>
北京新机场 严打无人机“黑飞”
查看>>
8点1氪|阿里巴巴第三财季营收破千亿;传滴滴拟裁员25%;饿了么口碑超30亿美元融资已逐步到位...
查看>>
程序员用代码将近200个小时,为自己DIY一个手机音乐播放器
查看>>
CentOS 7安装TCP BBR拥塞算法
查看>>
JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】...
查看>>
微软洪小文:真正的AI不应基于大数据,而需从小数据、零数据着手
查看>>