一句话总结:写屏障机制作用于GC过程,目的是为了维护在垃圾回收的收集过程中数据的一致性,实现GC的并发标记、三色不变性和低延迟,其实现是使用了混合写屏障(hybrid write barrier)技术,结合了Dijkstra风格的写屏障和Yuasa风格的写屏障的优点。
写屏障的工作方式
写前屏障(Dijkstra风格): 在指针修改前,将旧指针指向的对象标记为灰色
// 伪代码
func writePointer(slot *unsafe.Pointer, ptr unsafe.Pointer) {
shade(*slot) // 标记旧值
*slot = ptr // 实际写入
}
写后屏障(Yuasa风格): 在指针修改后,将新指针指向的对象标记为灰色
// 伪代码
func writePointer(slot *unsafe.Pointer, ptr unsafe.Pointer) {
*slot = ptr // 实际写入
shade(ptr) // 标记新值
}
写屏障的具体规则
在Go的混合写屏障实现中:
-
对全局变量和堆对象的写操作会触发写屏障
-
对栈上的写操作通常不需要写屏障(因为栈是根对象)
-
写屏障会确保:
-
被覆盖的旧指针指向的对象被标记
-
新写入的指针指向的对象被标记
-
写屏障的优化
Go运行时对写屏障做了多种优化:
-
无栈屏障: 栈上的写操作通常不启用写屏障,因为栈会被重新扫描
-
批量处理: 多个写操作可以批量处理以减少开销
-
条件启用: 只在GC的标记阶段启用写屏障
写屏障的重要性
写屏障使得Go能够实现:
-
并发标记: 用户程序可以和标记过程同时运行
-
三色不变性: 确保不会丢失任何可达对象的标记
-
低延迟: 减少了STW(Stop-The-World)的时间
内容主要来源于:Go语言写屏障机制详解
DISCUSSION
评论
还没有公开评论,欢迎留下想法。