Go垃圾回收

1.Go垃圾回收

go1.3之前使用标记清除算法

go1.5使用三色标记清除法和插入写屏障机制

go1.8结合删除写屏障机制,使用混合写屏障法

root对象:

根对象是指程序不需要通过其他对象就可以直接访问到的对象。如全局变量,执行栈。

1.1 标记清除法

普通标记清除法,整体过程需要启动STW,效率极低。

步骤

1.暂停程序业务逻辑,分类出可达和不可达的对象
2.标记所有可达对象
3.清除未标记的对象
4.结束暂停,继续执行程序。然后循环重复这个过程,直到程序生命周期结束

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3xDvPdrQ-1662516377017)(D:\go面试知识\photo\Snipaste_2022-09-02_17-26-52.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K8QAj6Df-1662516377018)(D:\go面试知识\photo\Snipaste_2022-09-02_17-27-47.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aaApXIyg-1662516377018)(D:\go面试知识\photo\Snipaste_2022-09-02_17-28-22.png)]

缺点:

1.让程序暂停
2.标记需要扫描整个heap
3.清除数据会产生heap碎片

1.2 三色标记清除法

三色标记法, 堆空间启动写屏障,栈空间不启动,全部扫描之后,需要重新扫描一次栈(需要STW),效率普通

1.2.1 步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TqWQbPrw-1662516377019)(D:\go面试知识\photo\Snipaste_2022-09-02_21-21-01.png)]

1.初始时,所有对象被标记为白色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzOp6G2r-1662516377019)(D:\go面试知识\photo\Snipaste_2022-09-02_21-21-37.png)]

2.遍历rootset,将直接可达的对象标记为灰色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rUY87D4H-1662516377019)(D:\go面试知识\photo\Snipaste_2022-09-02_21-22-40.png)]

3.遍历灰色对象,将直接可达对象标记为灰色,自身标记为黑色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-In2kwJ0X-1662516377020)(D:\go面试知识\photo\Snipaste_2022-09-02_21-23-21.png)]

4.重复第3步,直到标记完所有可达对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o2mxVVwJ-1662516377021)(D:\go面试知识\photo\Snipaste_2022-09-02_21-24-01.png)]

5.将标记为白色的对象当做垃圾回收掉
1.2.2 上述步骤的问题

上述三色标记法需要依赖STW(暂停程序),如果不暂停程序,程序的逻辑 改变对象引用关系,这种动作如果在标记阶段做了修改,会影响标记结果的正确性。

例子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVqpOdth-1662516377021)(D:\go面试知识\photo\Snipaste_2022-09-02_21-26-14.png)]

1.对象1可达 对象2,4;对象6可达对象7。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vdkSZNbi-1662516377021)(D:\go面试知识\photo\Snipaste_2022-09-02_21-27-22.png)]

2.对象2删除了对象3的引用,对象6创建指针指向对象3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X5SDJuE4-1662516377022)(D:\go面试知识\photo\Snipaste_2022-09-02_21-29-55.png)]

3.由于对象6不会再进行扫描,对象3一直会是白色标记,最后被当作垃圾回收掉

导致上文例子的情况,需要满足下面两个条件:

1.白色对象被黑色对象引用
2.灰色对象与白色对象之间的可达关系被破坏
1.2.3 两种不变式

解决1.2.2中的两个条件

  • 强三色不变式
不允许黑色对象引用白色对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n8hYy0cC-1662516377022)(D:\go面试知识\photo\Snipaste_2022-09-02_21-32-39.png)]

  • 弱三色不变式
黑色对象可以引用白色对象,但白色对象的上游必须存在灰色对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IMUz7iKV-1662516377022)(D:\go面试知识\photo\Snipaste_2022-09-02_21-33-26.png)]

1.2.4 屏障机制

为了遵循两种不变式,提出了两种实现机制

  • 插入写屏障

规则:当一个对象引用另一个对象时,将另一个对象标记为灰色

需要注意的是:

插入写屏障仅会在堆内存中生效,不对栈内存生效。因为go在并发运行时,大部分操作都发生在栈上,函数调用非常频繁。在栈上进行屏障保护会有性能问题。
1.2.4.1 插入写屏障执行过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHhroEwh-1662516377022)(D:\go面试知识\photo\Snipaste_2022-09-02_21-47-42.png)]

1.对象2标记为灰色,对象2引用对象3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8H6sfa2H-1662516377022)(D:\go面试知识\photo\Snipaste_2022-09-02_21-48-29.png)]

2.对象6创建一个指针,指向对象3。外界向对象1添加对象4。插入写屏障保证一个对象引用另一个对象时,另一个对象标记为灰色。但由于插入写屏障不作用于栈内存。所以对象3变为灰色,对象4为白色。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PL0Nf6W-1662516377023)(D:\go面试知识\photo\Snipaste_2022-09-02_21-50-06.png)]

3.对象2删除对象3的引用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kApxdYhD-1662516377023)(D:\go面试知识\photo\Snipaste_2022-09-02_21-50-07 .png)]

4.继续执行三色标记过程,结果如上图。

由于栈上的对象没有插入写屏蔽,在三色标记完成后,仍然可能存在栈上的白色对象被黑色对象引用(如对象4)。所以最后需要对栈上的空间进行STW,防止对象被误删除。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htKHBbvw-1662516377023)(D:\go面试知识\photo\Snipaste_2022-09-02_21-50-08.png)]

5.对栈空间执行STW

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfBXrLwI-1662516377023)(D:\go面试知识\photo\Snipaste_2022-09-02_21-50-09.png)]

6.对栈空间重新进行扫描,将对象4标记为黑色,最后垃圾回收白色标记的对象5和8,符合预期
  • 删除写屏障

规则:在删除引用时,如果被删除引用的对象自身为灰色或白色,那么被标记为灰色。

需要注意的是:

一个对象的引用被删除后,即使没有其他存活的对象引用它,它仍然会活到下一次GC执行。相当于本次GC有一些应该清除的对象没有清除,会产生很多的冗余扫描成本,降低了GC的精度。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cG9VODzB-1662516377024)(D:\go面试知识\photo\Snipaste_2022-09-05_08-47-48.png)]

1.2.4.2 删除写屏障执行过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vqhl4LEO-1662516377024)(D:\go面试知识\photo\Snipaste_2022-09-05_08-41-51.png)]

1.GC开始时使用STW扫描堆栈来记录初始快照。对象2标记为灰色,对象2引用了对象3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MeFL77it-1662516377024)(D:\go面试知识\photo\Snipaste_2022-09-05_08-42-24.png)]

2.被标记为黑色的对象6引用了对象3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vcqEtY00-1662516377024)(D:\go面试知识\photo\Snipaste_2022-09-05_08-43-09.png)]

3.灰色对象2去掉了对 对象3的引用,触发了删除写屏障(被删除引用的对象如果是白色或灰色,置为灰色),将对象3标记为灰色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o4ValNHK-1662516377024)(D:\go面试知识\photo\Snipaste_2022-09-05_08-44-43.png)]

4.遍历完所有可达对象,回收白色对象5,8,符合预期
1.2.4.3 两种屏蔽机制的总结

插入写屏障:

插入写屏障不能作用于栈内存,所以最后需要给栈空间进行STW,然后rescan保证引用的白色对象存活。

删除写屏障:

在GC开始时,会扫描记录整个栈做快照,从而在删除操作时,可以拦截操作,将白色对象置为灰色对象。
回收精度低。

1.3 混合写屏障

三色标记法,混合写屏障机制, 栈空间不启动,堆空间启动。整个过程几乎不需要STW,效率较高。

1.3.1 机制
1.GC刚开始时,将栈上所有可达对象标记为黑色
2.GC期间,任何在栈上新创建的对象,均为黑色。
3.堆上被删除引用的对象标记为灰色
4.堆上新添加的对象标记为灰色
1.3.2 步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56dbatoB-1662516377025)(D:\go面试知识\photo\Snipaste_2022-09-05_09-06-22.png)]

1.初始时,所有对象被标记为白色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4MIXS13d-1662516377025)(D:\go面试知识\photo\Snipaste_2022-09-05_09-06-55.png)]

2.GC开始时,将栈上所有可达对象标记为黑色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LjmeuQz0-1662516377025)(D:\go面试知识\photo\Snipaste_2022-09-05_09-07-27.png)]

3.开始三色标记,将对象6标记为灰色。同时栈上对象3新引用了对象9,触发混合屏蔽机制(GC期间,任何在栈上新创建的对象,标记为黑色),将对象9标记为黑色。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S1dpvn4M-1662516377025)(D:\go面试知识\photo\Snipaste_2022-09-05_09-09-10.png)]

4.在堆上创建对象10,对象6新引用了对象10,触发混合屏障机制(堆上新添加的对象标记为灰色),将对象10标记为灰色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WnwTOfcT-1662516377025)(D:\go面试知识\photo\Snipaste_2022-09-05_09-10-23.png)]

5.对象1引用了对象7,由于对象1在栈上,不会触发混合屏障机制,仅仅只是挂载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wGZGlE3W-1662516377026)(D:\go面试知识\photo\Snipaste_2022-09-05_09-11-10.png)]

6.对象6删除了对象7的引用,对象6在堆上,触发混合屏障机制(堆上被删除引用的对象,标记为灰色),将对象7标记为灰色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Is6SF6K1-1662516377026)(D:\go面试知识\photo\Snipaste_2022-09-05_09-12-24.png)]

7.将所有可达对象标记完成后,GC结束,最后将对象5,8回收
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值