内存溢出导致的Full GC异常

背景

   线上服务GC耗时过长,普遍10s+,此外GC后,内存回收不多

问题一

        通过查询gc日志可以发现,CMS进行垃圾回收的时候报concurrent mode failure错误,该错误是因为CMS进行垃圾回收的时候,新生代进行GC产生的对象晋升到老年代时,老年代空间无法满足需求,从而导致该异常

影响:当出现该异常时,CMS垃圾回收机制会退化成Serial Old,也就是说原本并行多线程进行垃圾回收退化成单线程回收,此时垃圾回收停顿时间就会变长,则就是为毛GC耗时长的原因

解决方案:

        首先我们需要了解CMS进行Full GC触发的时机是什么?从监控看当老年代达到92%时,则会触发GC,该值在jdk1.8后默认是92%(其实是可以计算出来的),可以通过-XX:+UseCMSInitiatingOccupancyOnly进行设置大小

问题二

        为什么GC后,老年代回收内存这么少?通过arthas dump下线上日志,利用Eclipse Meory Analyzer 进行分析,可以很直观看到是线上存活的WebCache中的ConcurrentHashMap对象占用过多,再根据代码进行分析即可找到问题所在

总结

        从以上分析可以了解到,其实是因为内存溢出导致老年代回收不及时,新生代晋升到老年代时空间不足,从而触发了CMS退化成Serial Old,导致GC耗时过长,从而拖垮整个系统性能。从中一个是需要处理内存溢出问题,第二个是可以通过-XX:+UseCMSInitiatingOccupancyOnly参数对GC触发的时机进行调节即可

其他

1.通过arthas 导出dump文件,可以使用命令 heapdump --live /tmp/dump.hprof

2.使用Eclipse Meory Analyzer 导入dump文件进行分析,可以使用Dominator Tree 或者Leak Suspects功能进行分析都是很强大的。

 

参考:

了解CMS GC触发时机:CMS的CMSInitiatingOccupancyFraction解析_insomsia的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值