跳转至

垃圾回收GC

GC

GC,全称 Garbage Collection,即垃圾回收,是一种自动内存管理的机制。垃圾回收机制是 Go 一大特点。

  • Go 1.3 采用标记清除法
  • Go 1.5 采用三色标记法
  • Go 1.8 采用三色标记法+混合写屏障

Go 1.3 标记清除法

分为两个阶段:标记和清除

  • 标记阶段:从根对象出发寻找并标记所有存活的对象。
  • 清除阶段:遍历堆中的对象,回收未标记的对象,并加入空闲链表。

缺点是需要暂停程序 STW。

Go 1.5 三色标记法:

将对象标记为白色,灰色或黑色

  • 白色:不确定对象(默认色);
  • 黑色:存活对象。
  • 灰色:存活对象,子对象待处理。

标记开始时,先将所有对象加入白色集合(需要 STW)。首先将根对象标记为灰色,然后将一个对象从灰色集合取出,遍历其子对象,放入灰色集合。同时将取出的对象放入黑色集合,直到灰色集合为空。最后的白色集合对象就是需要清理的对象。

这种方法有一个缺陷,如果对象的引用被用户修改了,那么之前的标记就无效了。因此 Go 采用了写屏障技术,当对象新增或者更新会将其着色为灰色。

Go 1.8 写屏障技术

一次完整的 GC 分为四个阶段:

  1. 准备标记(需要 STW),开启写屏障。
  2. 开始标记
  3. 标记结束(STW),关闭写屏障
  4. 清理(并发)

基于插入写屏障和删除写屏障在结束时需要 STW 来重新扫描栈,带来性能瓶颈。

混合写屏障分为以下四步:

  1. GC 开始时,将栈上的全部对象标记为黑色(不需要二次扫描,无需 STW);
  2. GC 期间,任何栈上创建的新对象均为黑色
  3. 被删除引用的对象标记为灰色
  4. 被添加引用的对象标记为灰色

总而言之就是确保黑色对象不能引用白色对象,这个改进直接使得 GC 时间从 2s 降低到 2us。

STW 是什么意思?

STW 可以是 Stop the World 的缩写,也可以是 Start the World 的缩写。通常意义上指指代从 Stop the World 这一动作发生时到 Start the World 这一动作发生时这一段时间间隔,即万物静止。STW 在垃圾回收过程中为了保证实现的正确性、防止无止境的内存增长等问题而不可避免的需要停止赋值器进一步操作对象图的一段过程。