CMS,也即Concurrent Mark Sweep,基于标记-清除算法实现。CMS的目标在于缩短STW时间(stop the world),适用于网站应用以及B/S架构的服务器端。
CMS垃圾回收器在进行垃圾回收时,主要经历以下步骤:
1. 初始标记
该阶段需要STW,工作线程需暂停。初始标记阶段的任务在于标记老年代、元空间中能够被GC Roots能够直接关联到的对象,老年代中可直接关联的对象可分为两种,被年轻代对象引用、被老年代对象引用。
2. 并发标记
该阶段无需STW,工作线程与标记线程并发执行。并发标记阶段,依据初始标记阶段标记过的GC Roots能够直接关联到的对象为起点开始遍历,标记所有可以遍历到的节点。
注意:
由于工作线程同步进行,所以在标记线程进行标记的同时,Old Gen中可能产生新的对象,这些新的对象在Old Gen产生时,会将其所在的Card标记为Dirty Card,这么标记的目的在于提高后续的重新标记的效率。
老年代产生新的对象的原因包括:
- 从Young Gen晋升过来
- 大对象直接在Old Gen分配空间
- Young Gen到Old Gen对象的引用关系发生变化等
3. 预清理阶段
通过并发标记,老年代可能产生了Dirty Card,该阶段的目的便是从Dirty Card对应的对象进行遍历,标记在并发标记阶段未能标记的对象。
4. 可终止的预处理
尝试着去承担下一个阶段Final Remark阶段足够多的工作。
5. 重新标记
该阶段产生STW。目的在于重新标记Old Gen所有存活的对象。在重新标记阶段,会对整个堆进行重新标记。因为阶段2、3、4中,工作线程与标记线程是同步进行的,所以新生代到老年代的对象的引用关系等均可能发生改变。(Young Gen也会有Dirty Card?不然感觉前面的操作没啥意义了,待研究!)
6. 并发清除
目的在于清除未被标记为存活状态的对象,完成垃圾收集。
7. 并发重置
进行重置,为下一次CMS垃圾收集做好准备。
参考链接: