golang GC混合写屏障

__robin · · 1941 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang混合写屏障实现

  1. 写屏障只应用在堆上应用,栈上部启用。

  2. GC开始将栈上的对象全部扫描并标记为黑色。

  3. GC期间,任何在栈上创建的新对象,均为黑色。

  4. 被删除的对象标记为灰色。

  5. 被添加的对象标记为灰色。

golang gc流程

  1. STW(StopTheWorld)开启写屏障,记录数据段以及栈中roots的必要信息

  2. StartTheWorld开始标记,此时mutator(用户程序)和GC标记并发执行

  3. 标记完成再次STW,关闭写屏障

  4. StartTheWorld进入轻扫阶段


其中标记阶段有一个问题很多文章没有解释清楚,就是,栈上的黑色对象是否会引用到一个堆上的白色对象。因为栈是没有写屏障的,如果栈上的黑色对象引用了堆上的白色对象,被引用的白色对象就会被GC错误回收。
例如下图所示的场景:

golang gc.png

A如果引用了D,同事B删除了对D的引用,那么D不就被错误的回收了吗。

实际这种情况时不会发生的:

  1. 对于某个goroutine的栈扫描是原子的操作,会暂停此goroutine,标记结束后栈对象全部为黑色。
  2. 已被扫黑的栈,引用的堆上的对象至少是灰色。(比如C对象)。所以不可能发生同栈下引用改变会影响GC的问题,因为白色对象都在保护之中。
  3. 不可能发生上述的跨栈的引用。因为“对象不是从天上掉下来的”。因为A没有路径能够抵达D。
  4. GC期间栈上新建的对象全是黑色,即使逃逸到堆上,也是黑色,所以A如果引用了新创建的对象也会是黑色,而不会发生错误的回收

参考:
golang 垃圾回收(五)深入剖析混合写屏障
Golang三色标记+混合写屏障GC模式全分析
go: GC时写屏障与栈的引用变化


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:__robin

查看原文:golang GC混合写屏障

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1941 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传