【Golang三色标记、混合写屏障GC模式图文全分析】https://studygolang.com/articles/27243?fr=sidebar
【垃圾收集器】https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-garbage-collector/
为了保证并发垃圾回收的正确性,需要做以下任一保证:
- 强三色不变性:黑色对象的下游不能有白色对象
- 弱三色不变性:黑色对象的下游可以有白色对象,但是必须有其他灰色对象可以到达该白色对象
为了能满足强三色不变性或者弱三色不变性需要引入屏障技术,屏障技术分为写时屏障和读时屏障,为了保证读取的快速性,golang中采用写时屏障技术。
写时屏障技术分为:
- 插入写屏障
- 删除写屏障
插入写屏障:对象插入或者更改时其插入的对象标记为灰色(满足强三色不变性),插入写屏障作用于堆内存。栈中处理方法有两种:
- 在栈中实现插入写屏障
- 在堆内存后进行栈的stw
考虑当goroutine较多时,在栈中实现插入写屏障开销较大,同时为了保证栈的快速性,固采用在堆进行标记清除后,对所有栈进行stw标记清除(缺点)
删除写屏障:在上游对象与下游对象断开连接时(删除),下游对象标记为灰色(为了满足弱三色不变性,下游对象和下游对象的下游对象有方法到达)
删除写屏障的缺点在于精度不够高,如果删除的下游对象并没有其他对象引用它时,下游对象原则上应该清除,但是此时没有清除(被标记了灰色,随后变为黑色),需要在下一次垃圾回收进行清除
混合写屏障:结合插入写屏障和删除写屏障的优点