什么时候会触发 fullGC
FullGC 在 JVM 中就是老年代发生垃圾回收。应用在发生 FullGC 的时候,应用线程会暂停业务操作,将 CPU 出让给垃圾回收线程进行工作。从而,造成应用 Stop The World 的现象。
发生 FullGC 的情况
主动调用 System.gc()
此操作建议虚拟机进行垃圾回收。但是,虚拟机会选择性执行。不建议使用此方式管理 JVM 内存。
未设置堆大小
在 JVM 初始化期间分配了一个较小的值(初始堆),随着应用程序的运行,会不断对堆大小进行调整。调整过程中,也会发生 Full GC。建议设置-Xms -Xmx。
老年代空间不足
大对象空间分配、长期存活的对象进入老年代。
空间分配担保
每次晋升的对象的大小大于空间剩余大小
年轻代 GC 后存活的对象超过了老年代的剩余空间大小
常见 GC 错误
注意 GC 日志中是否有 promotion failed 和 concurrent mode failure 两种状况,当出现这两种状况的时候就有可能会触发 Full GC。
promotion failed 一般是进行 Minor GC 的时候,发现 Survivor 空间不够,所以,需要移动一些新生代的对象到老年代。然而,有些时候尽管老年代有足够的空间,但是由于 CMS 采用标记清除算法,默认并不使用标记整理算法,可能会产生很多碎片,因此,这些碎片无法完成大对象向老年带转移,因此需要进行 CMS 在老年带的 Full GC 来合并碎片。(S 区空间小;老年代空间小或碎片多)。
concurrent mode failure 是在进行 CMS GC 过程,此时有对象要放入老年代而空间不足造成的,这种情况下会退化使用 Serial Old 收集器变成单线程的,此时是相当的慢的。
concurrent mode failure 错误
解释
此错误为 CMS 垃圾收集器特有的错误,CMS 的垃圾清理和引用线程是并行进行的,如果在并行清理的过程中老年代的空间不足以容纳应用产生的垃圾(也就是老年代正在清理,从年轻代晋升了新的对象,或者直接分配大对象年轻代放不下导致直接在老年代生成,这时候老年代也放不下),则会抛出“concurrent mode failure”。
原因
老年代中存活的数据太大,以致老年代没有足够空间支持分配,即导致 concurrent mode failure
如果长时间频繁出现,有可能是老年代设置太小或者 CMSGC 后没有进行压缩的原因导致
应用本身行为变化,导致 JVM 无法充分的预估新晋升对象的大小。(如:突然有一个非常大的对象,以致新生代无法存放,而老生代空间虽然大于平时预估对象大小,但是此对象老生代还是无法存放)
版权声明: 本文为 InfoQ 作者【技术小生】的原创文章。
原文链接:【http://xie.infoq.cn/article/bc97398a52e6cd2344b1bc575】。文章转载请联系作者。
评论