Go GC垃圾回收笔记
Go 1.3
标记清除法
-
进行STW,从main函数开始查找内存占用(根可达算法遍历)。
-
标记所有可以到达的内存占用。
-
标记完成后,清除这些内存占用。
-
结束STW,程序继续运行。
Go 1.5后
三色标记法
- 从根部(main函数)开始查找根可达对象,将这些可达对象标记为灰色,并放入灰色对象队列。
- 从灰色对象队列中取出灰色对象,并将其标记为黑色。同时将其引用的对象标记为灰色,放入灰色对象队列中。
重复以上两个步骤,直到灰色对象队列为空,此时剩下的所有黑色对象就是正在被使用的对象,所有白色对象就是要被清理的垃圾对象。
三色标记法+混合写屏障
-
初始化GC任务,包括开启写屏障和辅助GC,收集根对象。 这个阶段需要进行STW(Go 1.8后这一步的STW被取消了)。
-
扫描所有对象,包括全局指针和协程栈上的指针,(第一次扫描)扫描对应协程栈时需停止该协程(停止时间较短),执行三色标记,清空灰色对象队列,完成标记。 这个阶段在后台执行。
-
由于在三色标记的过程中可能会有新的对象加入,所以需要写屏障来记录这些新加入的对象。在三色标记完成后,重新扫描全局变量、指针和协程栈(第二次扫描),比对两次扫描结果,判断新加入的对象中是否有垃圾对象,或第一次扫描标记的白色对象中是否有被重写引用的,如果有,则将其重新标记为灰色,防止其被清除。此阶段需要进行STW。
-
按照标记结果回收所有的白色对象,这个阶段在后台执行。