Go GC
- STW,stop the world,启动写屏障,保证在标记期间新建的对象改变了依赖但不会被误清除,
- 标记可达的根对象为灰色
- start the world。
- 遍历标记的对象队列,将队列里对象的子节点标记为灰色,将原对象标记为黑色,放入黑色对象队列
- 循环执行4,直到没有灰色对象
- STW
- 禁用写屏障
- 这个时候只剩下白色对象和黑色对象,删除白色对象
- start the world
写屏障
因为 go 支持并发 GC, 所以GC的扫描和go代码可以同时运行,这样就会产生GC扫描的过程中go代码修改了对象的依赖树。
例如:
- 刚开始扫描时发现有对象A和B,B引用了C,
- GC先扫描A,将A标记为黑色
- 此时B将C的指针交给了A
- 然后扫描B,将B标记为黑色
- C最后是白色,会被回收掉,但实际上A引用了C
所以写屏障会在标记的时候将C放入灰色,防止被误清除。