Loading...

CMS的垃圾回收机制,为什么分为四步

2024-12-03

作者:Hap Tool

CMS(Concurrent Mark-Sweep Garbage Collection)垃圾回收器是Java虚拟机中的一种老年代垃圾收集器,属于基于标记-清除算法的实现。它的目标是尽量减少垃圾收集的停顿时间(即“低停顿”)。

简述

回答这个问题,应该先清楚CMS进行垃圾回收具体哪四个步骤:

1、初始标记(Initial Mark)

该阶段标记从GC Roots直接可达的对象。GC Roots包括全局静态对象、栈侦中引用的对象。这个阶段只需要标记和GC Roots直接关联的对象,标记范围比较小,STW的时间也比较短。这个阶段获取了一个基本的对象集合,从GC Roots开始明确哪些对象是存活的。

2、并发标记(Concurrent Mark)

该阶段不会再有STW,而是与应用程序并发进行。同时,在该阶段将会从GC Roots递归可达所有对象,确保所有存活的对象都会被标记。可想而知,由于遍历了所有对象,该过程也是最耗时的。

3、重新标记(Remark)

该阶段是为了修正并发标记过程中可能遗漏的存活对象。为什么会遗漏呢?因为并发标记中不会STW,应用程序在运行过程中,对象也产生了变化。为了保证重新标记的准确性,这个阶段会STW,也是整个CMS中暂停应用程序时间最长的阶段。

4、并发清除(Concurrent Sweep)

该阶段中,CMS将不再存活的对象从堆内存中移除。从名字中可以看出,该阶段不会STW,而是和应用程序并行处理。

结论

CMS作为垃圾回收器最终的目的是从内存中移除不再存活的对象,释放内存空间。在这个过程中,我们尽量减少对应用程序的影响,即减少STW的时间。从这个点上我们分析为什么要用了四个步骤。

从准确性上考虑,初始标记和重新标记确保所有的存活对象都能得到标记。

效率上,并发标记和并发清楚通过并行的方式减少STW的时间,提供内存回收效率,这在低延迟要求的业务场景中尤其重要。

同时CMS还支持调整JVM参数,根据不同业务场景的需求动态优化CMS的回收效果。例如在低延迟要求高的场景中,也可以配置如下参数将初始标记并行化,提高效率。

-XX:+CMSParallelInitialMarkEnabled

综上所示,CMS采取了比较灵活的方式,在确保准备性的情况下尽量的去减少STW的时间,提高JVM垃圾回收的效率。

同时需要提到的是,CMS虽然有时在面试中会问到,但是要了解的是他在JDK14中其实已经被移除了,而大多公司(尤其金融公司)可能还在使用JDK8. 在JDK9中,G1垃圾回收器已经成为主流,后面我也想聊聊他。