Go Runtime(五):GC、写屏障与Pacer

本文源码基线为 Go 1.26.2、Linux/amd64,默认 GOEXPERIMENT。Go 1.26.2 源码包含 build-tag 隔离的 Green Tea GC 实现,但默认 GOEXPERIMENT 下 goexperiment.GreenTeaGC == false;本文主线分析默认标记器,不把实验实现混入结论。 Go GC 的核心不是“三色”这个名词,而是在用户 goroutine 持续修改对象图时,怎样并发找出仍然可达的对象,并把暂停时间与 CPU、内存开销控制在目标范围内。 一轮 GC 可以理解为四套机制协作:标记算法判断对象生死,写屏障维护并发正确性,分配 goroutine 通过 assist 偿还标记债务,pacer 控制何时开始以及投入多少资源。 为什么需要GC 函数返回只能自然回收栈帧,无法决定堆对象是否仍被其他对象引用: GOtype Node struct { next *Node } func newNode() *Node { return &Node{} } 对象可能通过全局变量、其他堆对象、goroutine 栈或 runtime 结构继续可达。GC 必须从一组根出发遍历引用图,未被发现的堆对象才可以回收。 根对象 典型根包括: 全局变量和包级数据中的指针。 各 goroutine 活动栈帧中的指针。 寄存器或保存执行现场中的指针。 runtime 持有的特定对象引用。 编译器生成的类型位图和栈图告诉 GC 哪些位置是指针。Go 的标记器不会把任意看起来像地址的整数都当作指针,这提高了准确性,也要求 syscall、汇编和 cgo 遵守指针与栈管理规则。 ...

August 18, 2026