Appearance
垃圾回收
- GC:Garbage Collection,垃圾回收。
一些名词
垃圾内存
- 程序中不再被引用的对象(即 “垃圾”),释放其占用的内存,供新对象使用。
内存泄漏
- 程序在分配了内存但不再需要使用时,却未能正确释放这块内存空间,导致这部分内存被占用且无法再次使用,从而造成系统内存的浪费和性能下降。 这种问题会随着程序运行积累,最终可能导致程序甚至整个系统崩溃。
内存溢出
- 程序在申请内存时,无法满足当前需求,导致内存分配失败。
三色标记法
go gc主要算法是三色标记法(Tri-color Marking),通过将对象分为三种颜色来跟踪其状态:
- 白色:未扫描的对象(最终会回收)
- 灰色:已扫描但其引用的对象未扫描(处理中)
- 黑色:已扫描且其引用的对象均已扫描(存活)
GC 的原理
标记准备(STW,微秒级)
- 全局 STW,所有用户 G 停止运行,防止内存对象状态突变。
- 扫描所有根对象,将直接可达的对象标记为灰色,加入 “灰色队列”(待处理队列)。
- STW 结束,恢复所有业务 P/M/G 运行。
- 目的: 初始化标记环境、产出第一批灰色对象。
并发标记
- GC 协程 和 业务协程同时运行
- 从灰色队列中取出一个灰色对象,将其标记为黑色。
- 遍历该黑色对象引用的所有子对象:
- 如果子对象是白色,将其标记为灰色,并加入灰色队列。
- 如果子对象是灰色,忽略。
- 如果子对象是黑色,忽略。
- 循环直到灰色队列为空(初步标记完成)。理论可以全部标记为黑色。
标记终止(STW)
并发标记灰色队列为空后,进入该阶段。
- 暂停所有业务协程。
- 并发阶段栈上指针可能被业务代码修改,必须重新扫描根,补全遗漏标记。
- 处理残留灰色对象,彻底遍历,保证所有存活对象全部标黑。
- 关闭写屏障。
- 统计标记结果:区分存活对象(黑)、死亡对象(白)。
- STW 结束,恢复业务。
- 收尾标记,保证 100% 标记准确,杜绝并发期间的标记遗漏。
并发清扫
标记完成后,开始回收死亡对象,全程并发。
- 逐个判断对象颜色:
- 黑色:存活,保留,颜色暂时不变
- 白色:已死亡,回收内存,将内存放回堆空闲链表
并发重置
清扫完成后执行,为下一轮 GC 重置状态。
- 把本轮标记为黑色的存活对象,全部重新置为白色。
- 清空灰色队列、标记相关状态、计数器。
- 重置 GC 阈值、辅助 GC 标记状态。
- 本轮 GC 正式结束,等待下一次内存阈值触发。
