45

垃圾回收之写屏障

 3 years ago
source link: https://studygolang.com/articles/29761
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

资料阅读

有两张不错的gif图(原子wikipedia) https://zhuanlan.zhihu.com/p/74853110

最先看的文章,引用了上面的文章 https://www.jianshu.com/p/4c5a303af470

在讨论 Go 的混合写屏障 https://github.com/changkun/go-under-the-hood/issues/20

解释了为啥有 read barrier https://www.zhihu.com/question/42879518/answer/437304734

这些个文章看完,总觉得其中对golang的混合写屏障没说透,甚至感觉有错误说法。

三色标记的理解

iEFzuyB.gif

基本的mark-sweep算法

基本算法有个缺点,需要STW(stop the world),有较大延时。

BniMniE.gif

三色标记法(tricolor mark-sweep)

三色标记的过程中,节点颜色变化:白色》灰色》黑色。当没有灰色了,标记结束,黑色存活,白色清除。

三色标记可以实现增量回收和并发回收,能降低延时(latency);当然也有缺点,会降低吞吐量(throughput)。

三色标记正确运行需要满足下面2个条件中的一个:

  1. 强三色不变式:黑色对象不引用白色对象。
  2. 弱三色不变式:黑色对象引用的白色对象可以通过灰色对象搜索到。

当使用增量回收和并发回收时,回收过程中,用户程序会新建对象修改对象引用,会破坏上面的条件。写屏障就是为了处理这个事情。

有两套方案

// 当obj是黑色时,标记插入的*prt对象至少为灰色。满足强三色条件
// GC运行时,新new出来的对象,可以直接标记成黑色。
djjkstra_write_barrier(obj, ref, ptr){
    shade(ptr) // shade的做法时如果是白色就标记成灰色,否则不变。后面的伪代码都是这个意思。
    ref = ptr
}

// 从obj上删除ref时,标记*ref至少为灰色。这样可以满足弱三色条件
// 悲观认为所有被删的对象都可能被黑色对象引用了,效率很低的样子。
// **注意:**GC运行时,新new出的对象必须直接标记成黑色
yuasa_write_barrier(obj, ref, ptr){
    shade(ref) // 当obj时黑色时,可以不标记,因为删掉黑色到白色之类引用关系不破坏弱三色条件
    ref = ptr
}

一般来说dijk就挺好的,但像golang这种希望写栈上的引用时不使用写屏蔽,提高性能,所以得找别的方法。

  1. golang早期用的dijk的方法,得把栈本身重新标记成灰色,mark的最后阶段STW,然后扫描下栈,完成标记。这样说是最后结算的延时可以达到100ms。
  2. golang 1.8 用yuasa的方法,也同样存在同样的问题。这时可以当栈还不是黑色时,所有复制操作,额外把ptr标记成灰色,就当是从栈里删除下来的。
    伪代码
// golang 1.8的方式,说法是结合了dij和yuasa。效率(吞吐量)比yuasa还低。
// **注意:**GC运行时,新new出的对象必须直接标记成黑色
golang_hybird_write_barrier(obj, ref, ptr){
    shade(ref)
    // 当栈本身还没完成扫描时,假定ptr就是从栈上删除取下来的对象。当栈扫描完,可以当成标记为黑色,这时就不需要补充标记了。
    if current stack is grey: 
        shade(ptr)
    ref = ptr
}

这样就可以实现,栈里面的写操作不需要barrier处理,扫描最后也不需要STW重新扫描栈。

欢迎关注我们的微信公众号,每天学习Go知识

FveQFjN.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK