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())
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律