https://studygolang.com/articles/30067
关于三色收集和屏障技术的文章已经很多。先总结一下背景知识: 1. go使用混合屏障。删除屏障:假设A--ref-->B,ref断开时会对B染色。插入屏障:假设GC时,有新的引用C--ref2-->E,E也会被染色。 2. 上面的屏障保护只发生在堆的对象上。因为性能考虑,栈上的引用改变不会引起屏障触发。
先举个最常见例子:
附上代码:
writePointer(slot, ptr):
shade(*slot) // 删除屏障
if current stack is grey: // 这行可以忽略
shade(ptr) // 插入屏障
*slot = ptr
大部分文章,都在这戛然而止。留下无限的遐思。
然而,我们是思考者:
问题1很好解答,因为go是并发运行的,大部分的操作都发生在栈上。数十万goroutine的栈都进行屏障保护自然会有性能问题。
关键是,如果屏障不保护栈的引用,那如何保证正确性。
设想下面的场景:
因为这是一个伪命题: