Go-gc垃圾回收机制

1.什么是标记清除法?

首先要进行STW(stop the word - 程序暂停)

标记清除算法(Mark Sweep Algorithm),包括标记(Mark)和清除(Sweep)两个阶段:

  • 标记阶段:从根对象开始,查找并标记堆中所有存活的对象
  • 清除阶段:遍历堆中所有对象,回收未被标记的对象

2.标记清除法的缺点?

  • STW,stop the world;让程序暂停,程序出现卡顿 (重要问题)
  • 标记需要扫描整个heap;
  • 清除数据会产生heap碎片。

3.什么是三色标记法?

三色标记法将程序中的对象分为三类:白色、灰色和黑色

  • 白色:在回收开始阶段,所有对象都标记为白色;在回收结束后,所有白色对象均不可达,其内存将被释放
  • 灰色:已被垃圾收集器访问到的对象,是一种中间状态。
  • 黑色:已被垃圾收集器访问到的对象,且其引用都已被扫描到,黑色对象中任何一个指针都不可能直接指向白色对象
  • 初始状态:所有对象都是白色的
  • 扫描根对象:从根对象开始扫描,将所有可达对象标记为灰色,并放入待处理集合中
  • 处理灰色对象:从待处理集合中取出灰色对象,将它们引用的对象标记为灰色,并将这些新标记的对象加入待处理集合中,同时将自身标记为黑色。
  • 重复扫描:重复第3步,直到待处理集合为空。此时,所有白色对象都是不可达的垃圾对象,可以进行回收

3.没有STW下的三色标记法会遇到的问题?

条件1:一个白色对象被黑色对象引用(白色被挂在黑色下)

条件2:灰色对象与它之间的可达关系的白色对象遭到破坏(灰色同时丢了该白色)如果当以上两个条件同时满足时,就会出现对象丢失现象!

如果出现满足上面两个条件的场景就会把已经被指向的对象回收。如下图所示。

5、Golang三色标记混合写屏障GC模式全分析 · 语雀        

3.1 有哪些是根节点?

  • 全局变量:程序在编译期就能确定的那些存在于程序整个生命周期的变量
  • 执行栈上的对象或指针:每个 goroutine 都包含自己的执行栈,这些执行栈上2的对象包含栈上的变量及指向分配的堆内存区块的指针。
  • 寄存器中的变量:寄存器的值可能表示一个指针,参与计算的这些指针可能指向某些赋值器分配的堆内存区块

强弱三色不变性

  • 强三色不变形

强三色不变色实际上是强制性的不允许黑色对象引用白色对象,这样就不会出现有白色对象被误删的情况。

  • 弱三色不变性

弱三色不变式强调,黑色对象可以引用白色对象。但是要满足下面两者之一。

  1. 这个白色对象必须存在其他灰色对象对它的引用
  2. 它的链路上游存在灰色对象。 

为了遵循上述的两个方式,GC算法演进到两种屏障方式,“插入屏障”, “删除屏障”,“混合写屏障”。

什么是内存屏障

就是加入了一段代码进行赋值,比如写屏障将被引用对象标记为灰色。

什么是写屏障

在A对象引用B对象的时候,B对象被标记为灰色。(将B挂在A下游,B必须被标记为灰色)
满足: 强三色不变式

        空间的特点是容量小,但是要求相应速度快,因为函数调用弹出频繁使用, 所以“插入屏障”机制,在栈空间的对象操作中不使用. 而仅仅使用在堆空间对象的操作中.

为什么不在栈中使用?

        因为栈空间调用更加频繁,且更加快速,这里如果每次插入的时候都检查,会让栈的速度变慢,而栈空间和堆空间来比较的话,就是快,所以这里为了性能,不进行插入屏障,而是在最后再重新扫描一次

        因为仅在堆空间中引入屏障,所以栈空间中可能出现有一个黑色对象引入白色对象的情况。为了解决这个问题,要对栈重新进行三色标记扫描, 但这次为了对象不丢失, 要对本次标记扫描启动STW暂停. 直到栈空间的三色标记结束.

什么是删除屏障

具体操作: 被删除的对象,如果自身为灰色或者白色,那么被标记为灰色。
满足: 弱三色不变式.

混合写屏障

1、GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW),
2、GC期间,任何在栈上创建的新对象,均为黑色。
3、被删除的对象标记为灰色。
4、被添加的对象标记为灰色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值