GO GC
垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的对象,让出存储器资源,无需程序员手动执行。
Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可并发运行,但需要一定时间的STW(stop the world),STW的过程中,CPU不执行用户代码,全部用于垃圾回收。
Go1.3采用标记清除法, Go1.5采用三色标记法,Go1.8采用三色标记法+混合写屏障。
标记清除法(mark and sweep)
-
分为两个阶段:标记和清除
-
标记阶段:从根对象出发寻找并标记所有存活的对象。
-
清除阶段:遍历堆中的对象,回收未标记的对象,并加入空闲链表。
-
缺点:
- 需要暂停程序(STW)
- 标记需要扫描整个堆
- 清除数据会产生堆碎片
三色标记法
-
将对象标记为白色,灰色或黑色。
-
白色:不确定对象(默认色);黑色:存活对象。灰色:存活对象,子对象待处理。
- 将所有对象加入白色集合
- 从根节点开始遍历所有对象,把遍历到的对象从白色集合放入灰色集合
- 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
- 重复第三步, 直到灰色中无任何对象
- 回收白色集合所有的对象
- 缺点:对象的引用被用户修改了,那么之前的标记就无效
- 条件1: 一个白色对象被黑色对象引用(白色被挂在黑色下)
- 条件2: 灰色对象与它引用的白色对象遭到破坏(灰色丢了该白色)
- 当以上两个条件同时满足时, 就会出现白色对象丢失现象
- 解决:引入屏障机制
屏障机制
-
“强-弱” 三色不变式
- 强三色不变式:不存在黑色对象引用到白色对象的指针
- 弱三色不变式:所有被黑色对象引用的白色对象都处于灰色保护状态
-
插入写屏障
- 操作:在A对象引用B对象的时候,B对象被标记为灰色
- 满足:强三色不变式。
- 注意:在栈空间的对象操作中不使用,仅使用在堆空间对象的操作中
- 缺点:对栈重新进行三色标记扫描需要STW,直到栈空间的三色标记结束
-
删除写屏障
- 操作:被删除的对象,如果自身为灰色或白色,那么被标记为灰色
- 满足:弱三色不变式
- 缺点:回收精度低,一个对象即使被删除了最后一个指向它的指针仍可以活过这一轮
-
完整的GC分为四个阶段
- 准备标记(开启STW),开启写屏障。
- 开始标记
- 标记结束(停止STW),关闭写屏障
- 清理(并发)
混合写屏障
- 解决写屏障问题
- 注:不在栈上应用,因为要保证栈的运行效率
- GC开始:将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW)
- GC期间:在栈上创建的新对象标记为黑色、被删除的对象标记为灰色、被添加的对象标记为灰色
总结
-
GoV1.3- 普通标记清除法,整体过程需要启动STW,效率极低。
-
GoV1.5- 三色标记法, 堆空间启动写屏障,栈空间不启动,全部扫描之后,需要重新扫描一次栈(需要STW),效率普通
-
GoV1.8-三色标记法,混合写屏障机制, 栈空间不启动,堆空间启动。整个过程几乎不需要STW,效率较高。文章来源:https://www.toymoban.com/news/detail-669282.html
参考文章:Golang 垃圾回收文章来源地址https://www.toymoban.com/news/detail-669282.html
到了这里,关于GO GC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!