CMS回收并发失效与晋升失败

CMS垃圾回收失败类型主要是两种:并发失效和晋升失败

并发失效

新生代(YoungGen)发生垃圾回收时,达到晋升年龄的对象会被移动到老年代(OldGen)中。

如果老年代没有足够的空间容纳这个晋升对象,CMS为了腾出老年代空间,就会从本来的MinorGC退化成FullGC

MinorGC只回收新生代,而FullGC不仅回收新生代,而且还会回收老年代,永久区(PermGen)或元区(MetaSpace)空间回收也可能随FullGC顺便执行。

本来只是简单的新生代回收工作扩大到老年代甚至更大。除此之外,老年代空间通常比新生代的EdenSurvivor区大得多,检查和清理无效对象的时间要多得多。

还有,FullGC回收的同时,所有进程必须StopTheWorld,并用单线程(SerialGC)开始垃圾回收。导致本来可以并发的MinorGC变得缓慢无比。

晋升失败

晋升失败同样是老年代导致的问题。

CMS开启新生代垃圾收集的时候,判断老年代似乎有足够空间容纳所有晋升对象。

然而晋升的时候才发现老年代的空间竟然都是碎片化的,根本容纳不了一个完整的晋升对象。

剩下出路只有内存整理。所有应用运行的线程停止,CMS开始对老年代进行整理和压缩。

空间压缩要通过移动里面的对象,令这些对象排列好,所以晋升失败比不需要移动对象的并发失效更加浪费时间。

完成清理的堆空间变得规整和空余,继续运行应用。

调优

并发失效调优:

  • 令老生代垃圾回收提早,增大回收频率
  • 增大老年代空间
  • 增大新生代空间,提高对象滞留时间,更多新对象被回收而不是晋升。
  • 增加更多后台回收线程

晋升失败调优:

  • 有难度,因为CMS本身不能规整Compat内存,只能退化到SerialGC来做
  • 尝试用G1,G1的内存模型更加先进

你可能感兴趣的:(CMS回收并发失效与晋升失败)