Go GC发展过程

2.1 Go V1.3标记清除法

V1.3之前:
(1)停止业务(STW),标记可达对象
(2)清除 
(3)继续业务
缺点:1.卡顿;2.标记需要扫描整个Heap;3.产生Heap碎片
V1.3优化:
缩小STW范围,相比之前,现在STW不包含Sweep清除了

2.2 Go V1.5的三色标记法

Go语言中的垃圾回收主要应用三色标记法,GC过程和其他用户Goroutine可并发运行,但需要一定时间的STW
(1)新创建的对象,标记为"白色"
(2)每次GC回收从根节点开始遍历下一层所有对象,将遍历到的对象从白色集合放入"灰色"集合
(3)遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将灰色对象放入黑色集合
(4)重复第三步,直到灰色中无任何对象(白色-不可达,黑色-可达)
(5)回收白色对象
可能会有很多并发流程也会被扫描,执行并发流程的内存可能相互依赖,为了在GC过程中保证数据的安全,在开始三色标记之前会加上STW,在扫描确定黑白对象之后再放开STW
(因为如果不暂停程序,程序的逻辑会改变对象的引用关系,这种动作如果在标记阶段做了修改,会影响标记结果的正确性)

没有STW的三色标记法不安全
(1)条件1:一个白色对象被黑色对象引用(白色被挂在黑色下)。
(2)条件2:灰色对象与它之间的可达关系的白色对象遭到破坏(灰色同时丢了该白色)。

2.3 Go V1.5的屏障机制(无STW)

强三色不变式-插入屏障 (强三色不变色实际上是强制性地不允许黑色对象引用白色对象,这样就不会出现白色对象被误删的情况)

若三色不变式-删除屏障 (删除屏障的具体操作是,被删除的对象,如果自身为灰色或者白色,则被标记为灰色。删除屏障实际上是满足弱三色不变式,目的是保护灰色对象到白色对象的路径不会断)

缺点:
(1)插入写屏障:结束时需要STW重新扫描栈,标记栈上引用的白色对象的存活。
(2)删除写屏障:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象。

2.4 Go V1.8的混合写屏障

规则:
(1)GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无须STW)。
(2)GC期间,任何在栈上创建的新对象均为黑色。
(3)被删除的对象标记为灰色。
(4)被添加的对象标记为灰色。

总结

Go V1.3普通标记清除法,整体过程需要启动STW,效率极低。
Go V1.5的三色标记加插入写屏障或删除写屏障方法,在堆空间启动写屏障,而在栈空间不启动,全部扫描之后,需要重新扫描一次栈(需要STW),效率普通。
Go V1.8三色标记法加混合写屏障机制,在栈空间不启动屏障机制,而在堆空间启动屏障机制。整个过程几乎不需要STW,效率较高
posted @ 2023-11-21 21:53  longan55  阅读(81)  评论(0)    收藏  举报