面经-golang的gc算法

203 阅读2分钟

Golang的GC算法主要是基于标记-清扫(mark and sweep)算法,并在此基础上做了改进。

image.png

image.png

image.png

image.png

停止暂停让程序继续跑。然后循环重复这个过程,直到程序结束

  • 三色并发标记法(go 1.5)

image.png

image.png

  1. 第一步把所有对象默认为白色
  2. 每次gc开始后,从根节点开始遍历所有对象,把遍历到的对象从白色集合放入灰色集合
  3. 遍历灰色集合,将灰色对象引用的白色集合放入灰色集合,把此灰色对象放入黑色集合
  4. 重复第三步,直到最后没有灰色集合为止。。
  5. 回收全部的白色节点,也就是垃圾回收
  • 三色标记不希望发生的事(不添加stw) 条件:白色挂在黑色下同时灰色丢了该白色

image.png

会出现对象丢失现象

  • 如何再保证对象不丢失的情况下,提高gc效率,减少stw时间?

强三色不变式:强制性不允许黑色对象引用白色对象(破坏白色挂在黑色下)

弱三色不变式:黑色可以引用白色,但是白色链路上游有灰色引用(破坏灰色丢了白色)

image.png

  • 怎么满足强弱三色不变色 -- 屏障机制

image.png

image.png

  1. 插入屏障:a引用b,b被标记灰色(b在a的校下游,b为灰色),满足强三色不变色,不在栈上使用

image.png

image.png

image.png

image.png 不足:结束时需要stw来重新扫描栈,大约10-100ms

  1. 删除屏障: 被删除的对象,如果自身是灰色或者白色,那么被标记为灰色,满足弱三色(保护灰色到白色不会断)

image.png

image.png

image.png

image.png

保护5一轮,等待下一轮gc清掉。

image.png

go1.8 三色+混合写屏障

image.png

image.png

image.png

场景一:对象被一个对对象删除引用,成为栈对象下游

image.png

image.png