STW 是指在垃圾回收过程中,为了保证内存状态的一致性,暂时停止所有用户 goroutine 运行的一种机制。在 STW 期间,整个应用程序的代码都会停下来,只有 GC 相关的任务在运行。

STW 就是为了让 GC 能够安全、准确地清理内存而进行的“短暂闭市”

为什么需要 STW?

虽然 Go 使用的是并发垃圾回收(大部分工作和你的代码同时运行),但有些操作必须在“世界静止”的情况下才能安全完成:

  • 开启/关闭写屏障(Write Barrier):这是并发标记的基础。
  • 扫描根对象(Root Scanning):比如全局变量和各个 goroutine 的栈,确保初始状态的准确。
  • 阶段切换:在 GC 的不同阶段(如标记阶段到清理阶段)切换时,需要确保没有新的内存分配或引用变化干扰。

两个 STW 阶段

Go 的设计目标之一是低延迟,因此它极力压缩 STW 的时间:

  1. 标记准备阶段 (Sweep Termination)
    • 动作:清理上一轮 GC 剩余的任务,开启写屏障(Write Barrier)
    • 停顿原因:必须确保所有处理器(P)都进入安全点,一致开启写屏障。
  2. 标记终止阶段 (Mark Termination)
    • 动作:关闭写屏障,扫描一些在并发阶段产生的剩余根对象(如 Goroutine 栈、全局变量)。
    • 停顿原因:为了保证标记的完整性,必须在没有任何指针变动的情况下完成收尾。