回答
CMS 收集器是一款以获取最短回收停顿时间为目标的收集器,它用于老年代的垃圾回收,整个回收过程分为初始标记、并发标记、重新标记、并发清除四个阶段。各个阶段的主要工作如下:
- 初始标记阶段:该阶段,CMS 会暂停应用程序,并标记所有从
GC Roots
直接可达的对象。因为只需要标记根对象,所以这个阶段的停顿时间非常短。 - 并发标记阶段:该阶段,CMS 和应用程序会同时运行,CMS 从初始标记阶段标记的根对象出发,开始对整个对象图进行遍历和标记,标记从 GC Roots 可达的对象。
- 重新标记阶段:由于在并发标记阶段,收集器与应用程序同时进行,应用程序在运行过程中可能会对对象图进行修改,所以需要一个重新标记阶段来处理这些在并发标记期间发生变化的引用关系。在这个阶段,JVM 会再次暂停应用程序,CMS会重新扫描一些需要标记的对象,确保标记准确性。
- 并发清除阶段:在这一阶段,CMS 会清除那些在标记阶段判断为垃圾的对象,回收其内存空间。该阶段垃圾收集器与应用程序同时运行。
详解
一、初始标记阶段
在该阶段,JVM 会暂停应用程序的执行(STW)。CMS从GC Roots 开始,标记所有直接可达的存活对象,包括根对象直接引用的对象,以及被年轻代中所有存活的对象所引用的老年代对象。由于这个阶段只标注 GC Roots 能直接关联的对象,所以速度非常快。
目标:标记从 GC Roots 直接可达的对象,为后续的并发标记阶段做准备。
特点:短暂的 STW。
二、并发标记阶段
在该节点,CMS 收集器开始对整个堆内存进行完整的遍历,从“初始标记阶段”找到的根元素开始,标记所有可达对象。并发标记阶段是与应用程序并行执行的,所以,在这个阶段应用程序可以继续执行,不需要暂停。
目标:标记从GC Roots可达的所有对象,同时尽量减少对应用程序运行的影响。