GO-GC浅谈

1、什么是GC?

字面意思:垃圾回收,对于已经分配且不再有用的内存进行回收的管理机制或程序

2、为什么要GC?

防止内存溢出(OOM)

3、怎么GC?

GO的GC基于标记法,将对象分为三种颜色:黑色(有用对象)、灰色(被引用对象,不知道还有没有其他依赖对象)、白色(不被引用对象,需要被回收)。

GC算法:

从ROOT(全局对象、全局栈、goroutines栈)对象开始遍历,把它们引用(依赖)的对象标记为灰色

遍历灰色对象,如果当前灰色对象没有引用其它对象,则将当前灰色对象标记为黑色,如果当前灰色对象还引用了其它对象,则将当前灰色对象标记为黑色,同时将其引用的其它对象加入到灰色对象中

当遍历完灰色对象后,剩下的未被标记的对象就是白色对象,需要被回收

4、GC存在的问题

为了防止在GC过程中,其它goroutine运行改变对象引用关系,导致对象被错误回收(例如:刚开始A 未引用其它对象,B引用C,先扫描ROOT,A、B变成灰色,再扫描灰色A,A变成黑色,这时一个goroutine运行,删除了B对C的引用,添加了A对C的引用,GC扫描B的时候,B已经没有其它对象引用,直接变成黑色,由于A已经 扫描过,本次GC完成,C就变成白色被错误回收了),

老版本的Go,GC时需要STW(stop the world),即只能干GC一件事情,其它goroutine要阻塞,对于某些应用程序肯定是不能忍的

1.8引入了写屏障,基本不用STW

5、什么是写屏障?

STW主要有两个条件:

1、黑色对象新增了对白色对象的引用

2、白色对象没有被其它灰色对象引用

破环其中一个条件,就不用STW (A引用B改为A引用C)

针对第一种,用Dijistra写屏障,当新增黑色对象对白色对象的引用时,将白色对象(C)变成灰色。堆上的对象处理完后,还是需要STW对栈上的对象遍历

针对第二种,用Yuasa写屏障,当白色的对象被删除了一个引用时,将白色对象(B)变成灰色。一开始对栈上记录一个快照,整体结束后,再对比栈的快照差异,做一个小的STW

混合屏障,结合以上两种,将新增的(C)和删除的(B)都标记为灰色

6、什么时候GC?

  • 每次内存分配时,检查当前内存是否达到阈值,需要扩容时,触发GC
  • 定时触发GC(2min)
  • 手动触发GC(runtime.GC())

 

参考:【Golang】GC探秘/写屏障是什么? - 简书 (jianshu.com)

posted @   hugeQAQ  阅读(223)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示