频繁Young GC 问题记录

1、问题:连续gc

每10s左右发生“一组”gc,每组基本是三次,如果按组的gc频率来看还算正常,但这个“一组”连续三次gc属实不太正常。

频繁Young GC 问题记录_第1张图片

 

2、查看gc统计:jstat -gc 进程id 100

100ms的gc统计信息:其中连续gc三次,第一次gc后,发现内存每次增加80M左右,而第一次gc时其实eden还剩余40M的内存,所以判断此时有大对象在不断的快速生成。频繁Young GC 问题记录_第2张图片

 

3、jmap -histo:live 进程id |grep "cn" |head -20

想通过手动查看对比对象的内存占用信息,可惜一无所获,因为这根本是在盲猜。。。

 

4、jmap -dump:format=b,file=dump.hprof 进程id,dump出堆栈信息,然后通过MAT工具进行分析

在概览中提示有Unreachable Objects Histogram,即可以被gc回收的对象。频繁Young GC 问题记录_第3张图片

点进Unreachable Objects Histogram查看,排除基础类,可以看到rx包下的实例到达了一百万之多!!频繁Young GC 问题记录_第4张图片

对比Histogram(Reachable Objects Histogram,即不可回收的对象),差距巨大。频繁Young GC 问题记录_第5张图片

点开dominator_tree查看Merge Shortest Paths to GC Roots -> exclude all phantom/weak/soft etc.reference频繁Young GC 问题记录_第6张图片

可以看到hystrix的执行线程占有了大部分的引用,到此可以说产生大量的rx包下对象实例导致内存快速增长与hystrix的统计信息 可能有关系,但无法肯定,因为Unreachable Objects查看不了引用信息和相关大小。频繁Young GC 问题记录_第7张图片

于是利用排除法,我把项目中hystrix相关的都去掉了,然后部署观察,结果还是频繁的YoungGC,所以又把当前的堆栈信息dump出来继续找原因,发现tomcat中的一个对象实例数也异常高,怀疑tomcat配置部署问题。频繁Young GC 问题记录_第8张图片

 

5、使用jvisualvm工具实时查看

本想使用jvisualvm通过JMX远程连接监控,结果由于各种原因连不上,干脆就把tomcat拷贝了一份到本地启动调试,虽然不能完全模拟相同环境,但是先看看能不能复现问题。启动后问题就出现了(高兴啊啊啊!!),赶快jvisualvm连上看。

频繁Young GC 问题记录_第9张图片

频繁Young GC 问题记录_第10张图片

一看确实是tomcat的一个后台线程执行中占用了大量内存,结合源码看,是重加载引起的。查看配置,reloadable="true" 确实是允许重加载,那又是什么触发的?


       

       

看源码也看不出为什么,于是把tomcat的调试日志打印出来看,结果并没有打印"resourceModified"的日志,说明并没有真正执行重加载,而只是执行了modified()方法判断是否有资源修改时就发生了GC,因为modified()方法里面会遍历所有资源。

 

总结:一是不够细心,日志观察不到位;二是jdk工具用得还不够熟练,耽误时间;三是tomcat研究不够,源码还是要去看的。

 

其它知识:CPU占用率高排查

(1)登录服务器,执行top命令,查看进程占用CPU情况;
(2)top -Hp 进程ID,查看线程占用CPU情况;
(3)jstack 进程ID |grep -A 200 线程ID十六进制值,查看线程执行情况;
(4)找到该线程正在执行的代码,分析定位问题。

你可能感兴趣的:(jvm)