先说结论:这不是“会搬家的 GC”

Green Tea 最容易被标题带偏的地方,是把“回收器在堆里移动”理解成“活对象被搬到一起”。Go 1.26 的新回收器仍然是非移动式 mark-sweep:它从根引用出发标记仍可到达的对象,再把未标记空间交还给分配器。改变的是扫描工作的组织方式。旧路径更像把待扫描对象逐个放进全局工作队列;Green Tea 更强调按页聚集和扫描,让 CPU 在相邻内存上连续工作,减少等待内存的时间,也更容易利用多核和新硬件的向量指令。

Phil Eaton 的文章把这个抽象过程画成了可见的地址分布。程序随机分配不同尺寸的对象,再沿地址空间输出字符,读者可以看到同一 size class 的对象怎样聚进 span。这个画法特别适合中文图文或视频:先画对象与指针,再把“逐对象排队”和“按页聚集”并列,最后用 perf 数据说明缓存局部性为何会改变 GC CPU 成本。

稀疏页是这条内容真正有用的反面

非移动设计让 Go 避免了更新所有对象地址的复杂性,却也意味着只要一个 span 里还留着活对象,那些夹在中间的空位通常不能像压缩式 GC 那样通过搬家合并成完整空页。文章构造的分配与释放模式正是在观察这个问题:逻辑上已经释放许多对象,进程持有的页却未必等比例下降。

这不应直接写成“Go 1.26 内存泄漏”。泄漏通常意味着本应不可达的数据仍被引用;这里讨论的是可达对象的空间分布与非移动回收策略造成的碎片或稀疏页。可靠的实测要同时看 heap profile、RSS、分配率、GC CPU 与尾延迟,并固定 Go 版本、硬件和流量。Green Tea 已经是 1.26 默认项,迁移内容的重点也不是教读者永久关闭它,而是教会他们用自己的工作负载验证收益,在发现回归时保留 profile,并按官方要求反馈可复现证据。