Go(三)GC垃圾回收

5、Golang三色标记混合写屏障GC模式全分析 · 语雀本节为重点章节本章节含视频版:视频链接地址:https...https://www.yuque.com/aceld/golang/zhzanb

1. 核心痛点:STW (Stop The World)

在了解三色标记法之前,必须先了解 STW。 最原始的 GC(如 Go 1.0)在清理垃圾时,必须暂停整个程序所有的 Goroutine,不准任何人修改内存,然后慢慢扫描、清理,最后再恢复程序运行。这个全局暂停的时间就是 STW。如果内存很大,STW 会长达几百毫秒甚至几秒,这对高并发 Web 服务和游戏服务器是致命的。

因此,Go GC 演进的终极目标只有一个:将 STW 时间压榨到极致(目前通常在 1 毫秒以内),让 GC 过程和用户的业务代码并发执行。

2. 核心算法:三色标记法 (Tri-color Marking)

为了实现并发扫描,Go 将内存里的所有对象在逻辑上分为三种"颜色"状态:

  • ⚪ 白色(White): 潜在的垃圾。刚开始扫描时,所有对象都是白色的。如果扫描结束后还是白色,就会被当成垃圾回收掉。

  • 🔘 灰色(Grey): 存活对象。表示该对象已经被 GC 扫描到了,但它引用的其他对象还没被扫描完。灰色相当于一个待处理的工作队列。

  • ⚫ 黑色(Black): 绝对存活对象。表示该对象已经被扫描,并且它引用的所有子对象也都已经被扫描过了。黑色对象是安全的,绝不会被当成垃圾。

扫描工作流:
  1. 起步: 将所有对象标记为白色。

  2. 找根(Root): 从程序的根节点(如全局变量、当前运行 Goroutine 的栈变量)出发,找到它们直接引用的对象,把这些对象涂成灰色

  3. 顺藤摸瓜: 从灰色对象集合中取出一个对象,把它涂成黑色 。然后把它直接引用的所有白色子对象涂成灰色

  4. 循环往复: 重复第 3 步,直到内存里没有任何灰色对象为止。

  5. 一键清空: 此时,内存里只剩下黑色(存活的有用对象)和白色(没人要的孤儿对象)。直接把所有的白色对象清理掉(Sweep)。

3. 致命危机:并发标记的"丢包"问题

既然我们的目标是"并发",也就是 GC 在扫描变颜色的同时,用户的 Goroutine 还在疯狂运行、修改引用关系。这就会导致一个致命 Bug:存活的对象被当成垃圾误杀了。

误杀必须同时满足两个条件:

  1. 一个黑色 对象(已经扫描完不再回头看)突然指向了一个白色对象。

  2. 同时,那个白色 对象原本唯一依赖的灰色父节点,把这段引用给删除了。

结果就是:黑色对象拉住了白色对象,但由于黑色对象不会被二次扫描,这个白色对象永远变不成灰色和黑色,最终在清除阶段被冤死。

4. 终极解法:混合写屏障 (Hybrid Write Barrier)

为了解决并发误杀,Go 在 1.8 版本引入了混合写屏障技术。 "屏障"就像是内存操作的一个"钩子(Hook)"。当用户代码试图修改对象的引用时,会自动触发一小段额外的逻辑。

混合写屏障的精髓在于它破坏了误杀条件:

  • 无论你把一个引用改成指向谁,或者删除了对谁的引用,只要涉及引用的变动,系统都会强制把相关的对象涂成灰色。

  • 这是一种"宁可错杀(留下一点本该清理的浮动垃圾留到下个周期),绝不放过(绝不误杀存活对象)"的保底策略。

借助混合写屏障,Go 的 GC 就可以放心地和用户代码并发运行,只需要在极短的时间内进行 STW(用于开启屏障和做最后的收尾确认),极大地提升了性能

相关推荐
meilindehuzi_a3 小时前
从零理解并实现 RAG:用 LangChain.js 构建语义检索问答系统
开发语言·javascript·langchain
风流 少年3 小时前
Julia
开发语言·julia
江畔柳前堤3 小时前
GO01-Go 语言与主流编程语言深度对比
开发语言·人工智能·后端·微服务·云原生·golang·go
:-)4 小时前
算法-归并排序
java·开发语言·数据结构·算法·排序算法
GIS阵地5 小时前
QgsRasterDataProvider 完整详解(QGIS 3.40.13 C++)
开发语言·c++·qt·开源软件·qgis
yaoxin5211236 小时前
462. Java 反射 - 获取声明类与封闭类
java·开发语言·python
阿里嘎多学长6 小时前
2026-07-14 GitHub 热点项目精选
开发语言·程序员·github·代码托管
charlie1145141917 小时前
Cinux: 为大内核铺路
开发语言·c++·操作系统·现代c++
2501_914245937 小时前
C语言设计模式详解:从理论到实践的完整指南
c语言·开发语言·设计模式
Hazenix8 小时前
Go 指南:一篇文章速通 Golang
开发语言·后端·golang