美文网首页
go语言 GC混合写屏障

go语言 GC混合写屏障

作者: __robin | 来源:发表于2021-04-15 12:38 被阅读0次

    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时写屏障与栈的引用变化

    相关文章

      网友评论

          本文标题:go语言 GC混合写屏障

          本文链接:https://www.haomeiwen.com/subject/qbkdlltx.html