Java虚拟机通过分阶段标记(初始标记、并发标记、重新标记)与并发回收(如G1混合回收、ZGC/Shenandoah读屏障重定向),将STW拆解为多次极短暂停,显著降低GC停顿时间。

Java虚拟机通过分阶段标记与并发回收机制,把原本需要“Stop-The-World”(STW)完成的GC工作拆解成多个小步骤,让部分阶段与用户线程并发执行,从而显著减少停顿时间。
分阶段标记:避免一次性遍历整个堆
传统标记-清除算法在标记阶段必须暂停所有应用线程,遍历全部对象图。现代JVM(如G1、ZGC、Shenandoah)改用“增量更新”或“SATB(Snapshot-At-The-Beginning)”快照机制,将标记过程划分为初始标记、并发标记、重新标记等子阶段:
- 初始标记仅扫描GC Roots直接引用的对象,耗时极短,通常只需几毫秒
- 并发标记阶段允许应用线程继续运行,JVM后台线程逐步遍历对象图,同时通过写屏障记录期间发生的引用变更
- 重新标记只处理并发阶段产生的少量变动(如新创建或修改的引用),不再扫描全堆
并发回收:清理与应用线程并行进行
回收阶段也不再强制STW。例如:
- G1在混合回收(Mixed GC)中,只选定部分老年代Region与年轻代一起回收,且转移(Evacuation)阶段仍可并发标记剩余区域
- ZGC和Shenandoah采用“读屏障+指针着色”技术,对象移动(Relocation)全程与用户线程并发;应用线程访问对象时,由读屏障自动重定向到新地址,无需停顿等待
- 它们将对象复制、更新引用、更新TLAB指针等操作分散到多个短暂停顿(ZGC单次停顿
写屏障与读屏障:保障并发安全的关键基础设施
没有屏障机制,并发标记或移动对象会导致数据不一致。JVM通过轻量级屏障指令实现协调:
立即学习“Java免费学习笔记(深入)”;
- 写屏障插在引用赋值前/后(如obj.field = newObj),用于记录跨代引用或标记被修改对象,保证标记完整性
- 读屏障插在对象引用读取时(如x = obj.field),在ZGC中用于检测对象是否已重定位,并透明转发——这对Java代码完全透明
- 这些屏障开销极小,现代CPU能高效执行,是低延迟GC得以落地的底层支撑
基本上就这些。核心思路不是消灭GC,而是把重活拆开、把停顿压到毫秒级甚至消除,靠的是算法分阶段设计 + 硬件友好屏障 + 运行时协同调度。










