Full GC 的一些常见原因

1. System.gc()方法的调用

2. 老年代不足

3. 永久代不足

4. concurrent mode failure

concurrent mode failure是在执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间不足造成的(有时候“空间不足”是CMS GC时当前的浮动垃圾过多导致暂时性的空间不足触发Full GC)。

相关参数:-XX:+UseCMSInitiatingOccupancyOnly ,如果没有设置此参数,虚拟机会根据收集的数据决定是否触发(建议线上环境带上这个参数,不然会加大问题排查的难度)。

相关参数:-XX:CMSInitiatingOccupancyFraction=80,即老年代满80%时触发CMS GC。设置太高,就容易产生concurrent mode failure,设置过低,CMS GC又太过频繁。

相关参数:-XX:UseCMSCompactAtFullCollection=true,由于CMS没有对内存进行压缩,所以会有内存碎片,设置此参数,默认每次执行Full GC的时候会进行整理压缩,目前默认是true。

相关参数:-XX:CMSFullGCsBeforeCompaction=n,指定多少次不压缩的CMS GC刚才之后,跟着来一次带压缩的CMS GC。默认是0,表示每次发生forground的cms gc 都会进行压缩,但压缩会影响暂停时间,因此可以适当调整次参数。

5. promotion failed

minor gc时年轻代的存活区空间不足而晋升老年代,老年代又空间不足而触发full gc。

相关参数: -XX:SurvivorRatio=8,设置eden和survivor的比例,默认8:1。

相关参数: -XX:MaxTenuringThreshold=15,最多经过多少次minor gc后存活的年轻代对象会晋升老年代,默认15。

6. 统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间

当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC)。

原文链接:https://www.zhihu.com/question/41922036/answer/93079526)

你可能感兴趣的:(Full GC 的一些常见原因)