CMS并发标记阶段不需Stop The World,它从初始标记对象出发并发遍历整个对象图以标记所有可达存活对象,耗时最长但保障应用持续响应,依赖写屏障记录引用变更并为重新标记阶段修正漏标做准备。

CMS的并发标记阶段是整个回收过程中耗时最长、但不暂停应用的关键环节,它的核心目标是在用户线程持续运行的同时,准确识别老年代中所有存活对象。
并发标记做什么
它从初始标记阶段产出的“GC Roots直接可达对象”集合出发,沿着对象引用链逐层向下遍历(即进行GC Roots Tracing),把所有能到达的对象都打上“存活”标记。这个过程覆盖整个老年代堆空间,但完全与Java应用线程并发执行——用户请求照常处理,系统响应不受影响。
为什么需要它
初始标记只标出根对象,远远不够;而如果等到重新标记阶段才完整扫描,中间用户线程产生的新引用关系就可能被漏掉。并发标记正是为了在STW时间极短的前提下,尽可能完成大部分标记工作,为后续精确修正打下基础。
实际运行中的关键点
- 依赖写屏障(Write Barrier)记录并发期间的引用变更,比如新生代对象晋升或老年代内引用更新
- 会触发“预清理”和“可中止预清理”等辅助阶段,目的是尽量赶在重新标记前完成一次Young GC,减少跨代引用带来的重标压力
- 虽然不STW,但会占用额外CPU资源,可能轻微降低应用吞吐量
- 标记结果不是最终结论——因为用户线程还在改引用,所以必须靠后面的重新标记(Remark)来兜底修正
和重新标记的区别
并发标记是“主干扫描”,范围大、耗时长、不暂停;重新标记是“快速收尾”,只处理并发期间发生变动的少量对象(如卡表Dirty Card里记录的区域),必须STW但停顿很短(通常几毫秒到几十毫秒)。两者配合,才能在低延迟前提下保证标记准确性。


















