STW是JVM为保障GC准确性而强制暂停所有应用线程的关键机制,核心用于根节点枚举、重新标记、对象转移等阶段,确保堆对象图一致性,避免漏标或误删;不同收集器STW时长差异大,但无法消除。

GC 日志里标出的 Stop-The-World 阶段,不是“在等 GC”,而是 JVM 正在执行若干不可并发、必须冻结所有线程的关键动作。不同收集器在 STW 期间做的事有差异,但核心目标一致:确保堆中对象图的一致性,避免应用线程修改引用导致漏标或误删。
根节点枚举(Root Enumeration)
这是几乎所有 GC 的首个 STW 环节。JVM 要从 GC Roots(如栈帧中的局部变量、静态字段、JNI 引用等)出发扫描存活对象,就必须“拍下快照”——暂停所有线程,防止它们在扫描中途修改栈或寄存器里的引用值。HotSpot 利用 OopMap 快速定位 Roots,但前提是线程已停在安全点,上下文稳定。
重新标记(Remark)
主要出现在 CMS 和 G1 中。并发标记阶段允许用户线程运行,但可能导致对象关系变化(如老年代对象被新引用指向)。STW 的 Remark 阶段会重新扫描那些在并发期间被修改过的区域(如 Card Table 标记的脏卡、G1 的 Remembered Set 变更),修正标记结果。这一步耗时受并发期间写操作频率和范围直接影响。
对象转移与更新(Evacuation & Reference Update)
G1 的 Evacuation Pause、ZGC 的 Pause Relocate、Shenandoah 的 Degenerated GC 都在此阶段完成对象复制和指针修正。例如 G1 会将选定 Region 中的存活对象复制到新的空闲 Region,并同步更新所有指向原地址的引用(包括栈、寄存器、其他对象字段)。这个过程必须 STW,否则复制途中引用被改,就会出现悬垂指针。
初始标记(Initial Mark)
虽短但必 STW。它只做两件事:标记 GC Roots 直接可达的对象(如线程栈里的对象引用),并标记这些对象所在 Region 为“活跃”。后续并发标记就从这里开始。它不扫描整个堆,但必须冻结线程才能准确读取栈和寄存器状态——哪怕只停几毫秒,也属于 STW。
不复杂但容易忽略:日志里看到 “pause” 字样,不代表整段都在做 GC 计算;其中可能混着线程到达安全点的等待时间、RSet 更新、TLAB 填充重置等配套操作。真正耗时大头,往往藏在“Evacuation”或“Remark”这类关键词后面。

















