Go的GC垃圾回收机制

一.历史原因

go发展史上采用过的一些方法

  • go 1.3 之前使用标记清除

  • go 1.5 三色标记法

  • go 1.8 三色标记法 + 混合写屏障机制

垃圾回收设计的名词

  • 自动释放
  • 垃圾回收
  • 三色标记法
  • 内存管理
  • STW(stop the world) 全部停止执行

标记清除法

标记清除法过程

暂停程序业务逻辑

暂停程序,绘制程序和对象的可达关系。

找到所有的可达对象,并做上标记。

清除未标记对象

停止暂停

停止暂停,让程序继续跑,然后循环重复这个过程,直到程序生命周期结束。

标记清除的缺点

  • STW(stop the world):让程序暂停,程序出现卡顿(重要问题)

  • 标记需要扫描整个 heap(堆)

  • 清除数据会产生 heap 碎片

  • 可以对以上方法进行改进(如下图),缩短 STW 的返回,但是还是会很大。

三色标记法

三色标记法的流程

三色标记法中,要切记,灰色只是一种状态,我们进行遍历最后的结果,就是没有灰色节点。

创建程序

程序创建的时候,默认所有的对象都是白色
只要是新创建的对象,默认颜色就是白色

在这里插入图片描述

遍历对象(非递归调用,只遍历一次),得到灰色节点

在这里插入图片描述

切记这里的遍历,是从根节点出发。遍历到 对象1对象4,切记 只遍历这一步,二不是递归调用。,他会把遍历到的 对象1对象4加入到灰色标记表中

遍历灰色集合

对灰色节点进行遍历,把灰色几点能达到的点,标记为灰色节点,把自己标记为黑色节点。
在这里插入图片描述

重复遍历灰色标记表,直到不存在灰色节点。

在这里插入图片描述

灰色标记表只是一种中间状态,最终我们要把灰色标记表中的东西全部清理掉。只剩下要么都是白的,要么都是黑的

回收白色垃圾

三色标记法的问题

说白了,他的问题就在于黑色节点引用白色节点了,这个白色节点,如果不停留,就会被删除掉。

三色标记法不使用 STW 会出现的问题


在这里插入图片描述

三色标记法最不希望发生的事

  • 条件一: 一个白色对象被黑色对象引用

  • 条件二:灰色对象同时又丢了对该白色对象的引用

如果以上两个条件同时满足,那么就会出现对象丢失现象

强弱三色不变式

  • 强三色不变式: 强制性的不允许黑色对象引用白色对象 :破坏了条件一

  • 弱三色不变式: 黑色对象可以引用白色对象,但是要求白色对象的链路上游,存在灰色对象 :破坏了条件二
    在这里插入图片描述

只要满足了强三色不变式或者弱三色不变式其中任何一个条件,就可以保证对象不丢失。那么如何保证呢?就要借助于屏障机制。

屏障机制

什么是屏障

屏障就是相当于在正常的流程中,插入了一道工序,在某些个语言里,屏障也叫做 回调,Hook 或者 handler钩子函数

插入屏障和删除屏障

屏障机制在 go 语言里,分为两种,分别为 插入屏障删除屏障

插入屏障
对象被引用的时候,触发的机制

删除屏障
对象被删除的时候,触发的机制

插入屏障

具体操作: 在 A 对象引用 B 对象的时候,B对象被标记为灰色。(将B挂在A下游,B必须标记为灰色)

这样可以满足强三色不变式,因为不存在黑色对象引用白色对象的情况了,因为白色会被强制编程灰色。

插入屏障的问题

因为每次引用对象,都触发 插入屏障 的话,会影响性能;堆栈两种结构相比,栈对性能的要求更高,所以为了不影响 上的性能,是不执行插入屏障的,只有在 上才执行插入屏障。

那么栈是如何进行垃圾回收的呢?

是在 上的数据都扫描完了以后,然后启动 STW,再重新扫描一遍,标记完以后,进行删除。

删除屏障

被删除的对象,如果自身是灰色或者白色,那么就会被标记为灰色

满足: 弱三色不变式。(保护灰色对象到白色对象的路径不会断)

要删除对象2

对象2 删除以后,要把 对象2 变成灰色

接下来,把所有的白色对象删除掉。

从上边可以看出来,这样回收删不干净,部分节点要等第二轮CG才能删除

混合屏障

单独使用删除写屏障和插入写屏障存在的问题

插入写屏障的不足:
结束时,需要STW来重新扫描栈,大概需要 10~100ms

删除写屏障的不足:
回收精度低,一个对象即使被删除了,最后一个指向它的指针,也依旧可以活过这一轮,

三色标记 + 混合读写屏障

  1. GC开始,优先扫描栈,将栈上的可达对象全部扫描,并标记为黑色(之后不再进行第二次扫描,无需STW)。

  2. GC期间,在栈上创建的节点,也都是黑色。

  3. 被删除对象,标记为 灰色

  4. 被添加的节点,也标记为灰色

参考文献

https://www.bilibili.com/video/BV1wz4y1y7Kd?share_source=copy_web

posted @ 2021-07-04 21:26  沧海一声笑rush  阅读(421)  评论(0编辑  收藏  举报