Golang面试题:写屏障
插入写屏障
golang 的回收没有混合屏障之前,一直是插入写屏障,由于栈赋值没有 hook 的原因,所以栈中没有启用写屏障, 所以有 STW。golang 的解决方法是:只是需要在结束时启动 STW来重新扫描栈。这个自然就会导致整个进程的赋 值器卡顿,所以后面 golang 是引用混合写屏障解决这个问题。混合写屏障之后,就没有 STW。
删除写屏障
goalng 没有这一步,golang 的内存写屏障是由插入写屏障到混合写屏障过渡的。简单介绍一下,一个对象即使被 删除了最后一个指向它的指针也依旧可以活过这一轮,在下一轮 GC中被清理掉。
混合写屏障
- 混合写屏障继承了插入写屏障的优点,起始无需 STW 打快照,直接并发扫描垃圾即可;
- 混合写屏障继承了删除写屏障的优点,赋值器是黑色赋值器,GC期间,任何在栈上创建的新对象,均为黑 色。扫描过一次就不需要扫描了,这样就消除了插入写屏障时期最后 STW 的重新扫描栈;
- 混合写屏障扫描精度继承了删除写屏障,比插入写屏障更低,随着带来的是 GC 过程全程无 STW;
- 混合写屏障扫描栈虽然没有 STW,但是扫描某一个具体的栈的时候,还是要停止这个 goroutine 赋值器的工 作的哈(针对一个 goroutine 栈来说,是暂停扫的,要么全灰,要么全黑哈,原子状态切换)。