CMS GC
回收策略
CMS GC的全称是最大并发标记清除垃圾回收器(Mostly Mark andSweep Garbage Collector),可以使用-XX:+UseConcMarkSweepGC开启。CMS GC的新生代清理仍然使用与Parallel GC类似的方式,即开启多个线程一起清理,且在这个过程中,Mutator线程不能工作。从算法上来说,该过程与Serial GC、Parallel GC的YGC完全一致;从逻辑上来说,该过程与Parallel GC的Young GC几乎一致,所以这里不再赘述。不同点是CMS GC多了个专门针对老年代的Old GC,图10-8简单说明了Old GC的概念。
图10-8 CMS GC
垃圾回收策略有很多名称,如Young GC、Full GC、Minor GC、Major GC和Mixed GC等,实际上对于HotSpot VM来说,只有Partial GC和Full GC。Partial GC表示只清理堆的部分区域。Minor GC与Young GC等价,都表示只清理新生代,Old GC表示只清理老年代,Mixed GC表示清理整个新生代和部分老年代,它们都属于Partial GC。Full GC表示清理整个堆,通常它等价于Major GC。本文主要是用Young GC(以下简称YGC)和Full GC(以下简称FGC)两种表示。
CMS GC除了有负责清理新生代的YGC、特殊情况下的FGC外,还有只回收老年代的垃圾回收策略,即Old GC。Old GC大部分过程允许Mutator线程和GC线程一起进行,此时Mutator线程无须停止,这种方式称为并发垃圾回收,所使用的算法称为并发标记清除算法。
对象丢失问题
传统的标记清除算法分为标记、清除两个阶段。为了将它改造为并发算法,CMS GC将标记清除算法细分为初始标记、并发标记、预清理、可中断预清理、重新标记、并发清理,重置几个阶段,其中只有初始标记和重新标记需要STW,其他最耗时的阶段允许GC线程和Mutator线程一起进行。正是因为它有两个阶段需要STW,所以CMS GC的名字是最大程度(Mostly)的并发而非完全(Completely)并发。Mutator线程和GC线程一起工作会造成一些问题,如图10-9所示。
图10-9 并发标记问题
三色抽象(Tricolor Abstraction)可以简洁地描述回收过程中对象状态的变化,所以本节将使用三色抽象描述对象标记过程:图10-9中黑色表示对象及成员都被处理,浅色网格表示对象本身已处理,白色表示未处理对象。
起初垃圾回收器已经处理了A、B、C对象,并正在处理E对象成员。由于Mutator线程可以与GC线程一起工作,所以Mutator线程可以更新B对象的引用,使其指向D对象,并删除G对象对D对象的引用。由于B对象已经被标记为黑色对象,不会再做扫描,所以GC只会继续处理E对象,并清扫未被标记的D对象。更进一步,研究表明,只要