golang 三⾊标记+GC混合写屏障机制
Go V1.3 之前的标记清除(mark and sweep)
流程:
第⼀步,暂停程序业务逻辑, 找出不可达的对象,和可达对象。
第⼆步, 开始标记,程序找出它所有可达的对象,并做上标记。
第三步, 标记完了之后,然后开始清除未标记的对象.
第四步, 停⽌暂停,让程序继续跑。然后循环重复这个过程,直到process程序⽣命周期结束。
缺点:
STW,stop the world;让程序暂停,程序出现卡顿 (重要问题)。
标记需要扫描整个heap
清除数据会产⽣heap碎⽚
将第四步和第三步换位置, 缩短STW的范围
Go V1.5 三⾊标记法
流程:
第⼀步 , 就是只要是新创建的对象,默认的颜⾊都是标记为“⽩⾊”
第⼆步, 每次GC回收开始, 然后从根节点开始遍历所有对象,把遍历到的对象从⽩ ⾊集合放⼊“灰⾊”集合。
第三步, 遍历灰⾊集合,将灰⾊对象引⽤的对象从⽩⾊集合放⼊灰⾊集合,之后将 此灰⾊对象放⼊⿊⾊集合
第四步, 重复第三步, 直到灰⾊中⽆任何对象.
第五步: 回收所有的⽩⾊标记表的对象. 也就是回收垃圾
如果三⾊标记法不被STW保护
条件1: ⼀个⽩⾊对象被⿊⾊对象引⽤ (⽩⾊被挂在⿊⾊下)
条件2: 灰⾊对象与它之间的可达关系的⽩⾊对象遭到破坏 (灰⾊同时丢了该⽩⾊)
两个条件同时满⾜,那么就会出现对象丢失的现象
强弱三⾊不变式
强三⾊不变式 破坏条件1 强制性的不允许黑色对象引用白色对象
弱三⾊不变式 破坏条件2 白色对象存在其他灰色对象对其的引用 或者可达它的链路上游存在灰色对象
如果三⾊标记满⾜强弱不变式之⼀,即可保证不丢失对象
屏障机制
插⼊屏障
对象被引⽤时 触发的机制
具体操作: 在A对象引⽤B对象的时候,B对象被标记 为灰⾊。(将B挂在A下游,B必须被标记为灰⾊) 满⾜: 强三⾊不变式. (不存在⿊⾊对象引⽤⽩⾊对象的 情况了, 因为⽩⾊会强制变成灰⾊)
不⾜ 结束时需要STW来重新扫描栈,⼤约需要10~100ms
删除屏障
对象被删除时 触发的机制
具体操作: 被删除的对象,如果⾃身为灰⾊或者⽩⾊,那 么被标记为灰⾊。 满⾜: 弱三⾊不变式. (保护灰⾊对象到⽩⾊对象的路径不 会断)
不足 回收精度低, ⼀个对象即使被删除了最后⼀个指向它的指针也依旧可以活过这⼀轮, 在下⼀轮GC中被清理掉。
Go V1.8 混合写屏障机制
具体操作
1、GC开始将栈上的对象全部扫描并标记为⿊⾊(之后不再进⾏第⼆次重复扫描,⽆需STW)
2、GC期间,任何在栈上创建的新对象,均为⿊⾊。
3、被删除的对象标记为灰⾊。
4、被添加的对象标记为灰⾊。
满⾜: 变形的弱三⾊不变式. (结合了插⼊、删除写屏障两者的有点)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix