聊聊Go的三色标记法
这里是Z哥的个人公众号
每周五11:45 按时送达
当然了,也会时不时加个餐~
我的第「203」篇原创敬上
标记出哪些对象是存活的,哪些是可回收的。
进行回收(清除/复制/整理)。如果在回收期间有移动过的对象(复制/整理),还需要更新引用。
标记 GC ROOT 能关联到的对象。这里会 STW。
从 GCRoots 的直接关联对象开始遍历整个对象图。这里不会STW。
白色,初始值。本次回收没被扫描过的对象默认都是白色的。而确认不可达的对象也是白色,但是会被标记「不可达」。
灰色,中间状态。本对象有被外部引用,但是本对象引用的其它对象尚未全部检测完。
黑色,本对象有被其它对象引用,且已检测完本对象引用的其它对象。
在断开引用的时候做额外处理。
在「黑色」对象重新建立「白色」对象的引用时做额外处理。(回收开始后新建的对象默认为黑色)。
增量更新(Incremental Update)。针对新增的引用,将其记录下来等待重新遍历。这个操作在「修改操作后」进行,JVM 中的 CMS 垃圾回收器就是这个思路。
原始快照(Snapshot At The Beginning,SATB)。当某个时刻 的 GC Roots 确定后,当时的对象图就已经确定了。如果期间发生变化,则可以记录起来,保证标记依然按照原本的视图来。这个操作在「修改操作前」进行,JVM中 的 G1 垃圾回收器用的就是这个思路。理论上,配合 「Remembered Set」,SATB 的效率是比增量更新要高的,不过会消耗更多的内存。
将对象分为堆上的对象和栈上的对象。
GC 开始将栈上的对象全部扫描并标记为黑色,无需 STW。并且之后不再进行第二次重复扫描
在 GC 期间,任何在栈上创建的新对象,均为黑色。
在 GC 期间,在堆上被删除或者添加的对象都标记为灰色。后续继续扫描。
白色,默认值。本次回收没被扫描过的对象都是白色的。确认不可达的对象也是白色,但是会被标记「不可达」。
灰色,中间状态。本对象有被外部引用,但是本对象引用的其它对象尚未全部检测完。
黑色,本对象有被其它对象引用,且已检测完本对象引用的其它对象。
将对象分为堆上的对象和栈上的对象。
GC 开始将栈上的对象全部扫描并标记为黑色,无需 STW。并且之后不再进行第二次重复扫描
在 GC 期间,任何在栈上创建的新对象,均为黑色。
在 GC 期间,在堆上被删除或者添加的对象都标记为灰色。后续继续扫描。
推荐阅读:
原创不易,如果你觉得这篇文章还不错,就「点赞」或者「在看」一下吧,鼓励我的创作 :)
也可以分享我的公众号名片给有需要的朋友们。
如果你有关于软件架构、分布式系统、产品、运营的困惑
可以试试点击「阅读原文」