并发预处理旨在减少重新标记阶段的停顿时间,它通过扫描卡表中标记为“脏”的卡页,对其中对象进行局部重标记,以提前处理并发标记期间因用户线程修改引用而产生的变动,该阶段并发执行且可中止。

并发预处理(Pre-Clean)是 CMS 垃圾收集器在老年代回收过程中一个关键的中间阶段,位于并发标记之后、重新标记之前,主要目标是**减少重新标记阶段的停顿时间**。
为什么需要并发预处理
在并发标记阶段,用户线程(Mutator)持续运行,可能修改对象引用关系(如将老年代对象赋值给新生代对象、或修改老年代内引用),导致部分已标记对象的状态“过期”。这些变化若全部留到重新标记(Remark)阶段处理,会显著延长 STW 时间。并发预处理就是提前处理一部分这类“脏卡”(Dirty Card),降低 Remark 的工作量。
它具体做什么
该阶段依赖**卡表(Card Table)**机制:堆被划分为固定大小的卡页(通常 512B),每次对老年代对象的引用更新(尤其是跨代写操作),JVM 会通过写屏障(Write Barrier)把对应卡页标记为“脏”。并发预处理就扫描这些脏卡,对其中涉及的对象做局部重标记(re-mark),并尝试清理部分因引用变更而变成垃圾的对象。
- 只处理已知脏卡,不遍历整个老年代,开销可控
- 不保证完全覆盖所有变动——剩余未处理的脏卡,会在后续的重新标记阶段统一兜底
- 本身是并发执行的,用户线程不停止,但会短暂暂停以配合卡表扫描
和可终止预处理(Abortable Preclean)的关系
CMS 实际常启用的是“可终止预处理”,它是并发预处理的增强版:在进入重新标记前,它会循环执行若干轮预清理,并在每轮后检查是否已满足条件(如脏卡数量低于阈值、或已运行足够长时间)。一旦达标,就提前退出,避免无谓等待;否则继续下一轮。这种设计让 CMS 更灵活地平衡并发开销与 STW 时长。
注意点
这个阶段仅存在于 CMS 收集器(-XX:+UseConcMarkSweepGC),G1 和 ZGC 等现代收集器采用不同机制(如 G1 的 Remembered Set + SATB 写屏障)来应对并发修改问题,不再划分出独立的“预处理”步骤。











