golang垃圾回收 三色清除

目录

 

 

标记清除

算法

1、标记 (mark phase)

2、清除 (mark phase)

缺点

优化

三色标记

原理

问题:

屏障技术

原理

写屏障

删除屏障

混合写屏障


 

标记清除

算法

1、标记 (mark phase)

stw ,找到所有不可达的对象,做好标记

img

2、清除 (mark phase)

清除未标记的对象

img

缺点

1、stw , 暂停整个程序

2、标记需要扫描整个heap

3、清除数据会产生碎片

优化

1.3版本前,整个过程都在stw范围内

img

1.3做了优化,尽在标记阶段暂停。

img

三色标记

原理

三色标记的过程就是确认哪些对象不可达的过程。具体的过程如下:

1、所有新创建的对象都标记为白色

img

2、从根节点出发,能够直接到达的对象,标记为灰色

img

3、从灰色节点出发,可以到达的白色对象标记为灰色,原灰色节点标记为黑色。循环往复直至灰色标记为空

img

img

4、回收所有依然是白色标记的对象。

img

问题:

在三色标记中,黑色节点是不会重复扫描的,所以,如果没有stw就会出现一下两个问题:

1、白色对象被黑色对象引用 (白色对象会被删除)

2、灰色对象与其可达的白色对象之间的链路被破坏(破坏点之后的白色对象会被清除,因为链路断了扫描不到)

stw是解决以上问题的最好办法,但是stw不是我们想要的,所以出现了屏障技术

屏障技术

原理

GC过程中,满足以下条件之一,那么对象就是安全的:

1、强三色不变式 , 即不存在黑色对象引用白色对象的指针

img

2、弱三色不变式 ,即黑色对象引用的白色对象,处于灰色对象保护状态之下(扫描链路可达)

img

写屏障

写屏障,就是强三色不变式的实现:在对象A引用对象B的时候,B对象标记为灰色。

     栈空间操作频繁是没有写屏障的,所以需要stw保护。

流程如下:

img

 

img


 

img


 

img


 

img


 

img


但是如果栈不添加,当全部三色标记扫描之后,栈上有可能依然存在白色对象被引用的情况(如上图的对象9). 所以要对栈重新进行三色标记扫描, 但这次为了对象不丢失, 要对本次标记扫描启动STW暂停. 直到栈空间的三色标记结束.


 

img


 

img


 

img


最后将栈和堆空间 扫描剩余的全部 白色节点清除. 这次STW大约的时间在10~100ms间.


 

img

缺点:栈空间没有写屏障的保护,所以仍然需要stw的保护。

删除屏障

删除屏障是弱三色不变式的实现,即被删除的对象,如果自身为灰色或者白色 , 那么标记为灰色。

过程:

img


 

img


 

img


 

img


 

img


 

img


 

img

缺点:

1、开始阶段STW整个栈空间

2、会有浮动垃圾,因为被断开的链路有可能是垃圾,但是仍然被置为灰色了。

混合写屏障

针对写屏障和删除屏障的缺点,1.8版本引入了混合写屏障机制,避免了对栈的re-scan的过程,极大的减少STW时间。

优点:全程无STW , 但是针对单个goroutine来讲 , 是有STW的

缺点:继承了删除屏障的收集精度问题

简要流程:

1、GC并发标记所有栈空间的对象为黑色

2、GC期间任何栈上的新对象,标记为黑色

3、被删除的对象标记为灰色

4、新添加的对象标记为灰色

img

img

 

 

四种场景:

1、堆对象被一个堆对象删除引用,成为栈对象的下游:因为被引用的对象是堆空间的,触发写屏障,标记为灰色

img


 

img

2、堆对象被一个堆对象删除引用,成为某个堆对象的下游 , 同样触发写屏障机制

img


 

img


 

img

 

 

对象从一个栈对象删除引用,成为另一个堆对象的下游

img


 

img


 

img

对象被一个栈对象删除引用,成为另一个栈对象的下游

img


 

img


 

img

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值