混合GC(Mixed GC):既收集年轻代,也收集老年代。不同于YGC,涉及老年代回收时,引入了并发标记。并发标记指的是GC线程可以和Mutator线程同时运行。
并发标记
并发标记的难点在于如何在标记对象时,Mutator更改对象引用关系,从而导致漏标和错标的情况,错标不影响正确性,会多一些浮动垃圾。而漏标会导致可达对象被回收掉。为了区别不同对象的状态,引入了三色标记法。
三色标记法
三色标记法将对象分为白色(未被标记过),灰色(自身被标记过,field还未处理完),黑色(自身和field都被标记过)。并发标记漏标的场景有:
- Mutator插入一个黑色到白色的引用;
- Mutator删除了所有灰色到白色的引用;
如果2个场景都存在,则打破一个场景即可。对应的解法方法有: - 增量更新算法关注对象引用插入,将被更新的改为灰色;
- SATB关注引用的删除,对象被赋值前,将老引用记下来并以这些对象为根重新标记。
混合回收步骤
- 并发标记:初始标记、并发标记、再标记、清理
- 垃圾回收
初始标记
和ygc一样,标记直接可达根(栈、全局、jni对象等)
并发标记
当ygc结束后,如果老年代已使用内存达到InitiatingHeapOccupancyPercent(默认为45%)开始并发标记。由ConcGCThreads数量的线程进行标记,每个线程每次只处理一个分区。此阶段和Mutator线程并发运行。
再标记
STW,找出所有未被访问的存活对象,保证所有对象都被标记。
清理
STW,统计存活对象,用于下一次CSet选择;重置RSet;全是垃圾对象的分区放到空闲分区列表。值得注意的是,这个阶段不会进行垃圾对象清理。