GC垃圾回收
作者:互联网
GC垃圾回收
地址:https://www.bilibili.com/video/BV1wz4y1y7Kd?spm_id_from=333.999.0.0
1. Go V1.3 之前标记清除法(mark and sweep)
程序可达对象有1->2->3
,4->7
等五个对象;
在进行垃圾回收时,为了避免程序错乱,首先会进行STW(stop the world),将程序业务逻辑进行暂停,然后将程序可达对象全部进行标记,未被标记的对象被视为垃圾需要进行回收。垃圾回收完成后,解除STW,程序继续执行;
标记清除法的缺点:
- 存在STW过程,会让程序暂停,程序会出现卡顿现象主要问题;
- 标记需要对整个
heap
扫描,耗时长; - 清除数据会产生
heap
碎片;
优化:
尽量缩短STW时间,将垃圾清除和停止STW进行互换,缩短STW时间,即先解除STW,然后执行垃圾回收(上面三、四步之间进行交换)。但是标记时间任然过长;
2. Go V1.5 三色标记法
程序可达对象有1->2->3
,4->7
等五个对象;
三色:白、灰、黑,分别对应三色标记表,其中灰色为临时状态,最终态为白色或者黑色;
初始将程序所有对象标记为白色,遍历一次程序根集合,将一次比那里可达对象标记为灰色,然后将可达对象由白色标记为灰色,并将对象移至灰色标记表;然后遍历灰色标记表,将可达对象由白色变为灰色,遍历之后的灰色变为黑色。重复之前操作,直到灰色标记表没有数据。最后剩余的白色对象即为垃圾。
如果三色标记过程中不启用STW:
- 条件1:当一个白色对象被一个黑色对象引用(白色挂载在黑色下),如图对象3挂在对象4下;
- 条件2:灰色对象与该白色对象之间可达关系被破坏(灰色丢了该白色),对象2丢失了对象3;
如果上述两个条件同时满足,就会造成对象丢失(会导致对象3丢失),所以还是要加STW;
解决办法:阻止上述两个条件同时成立
- 强三色不变式:强制性的不允许黑色对象引用白色对象(破坏条件1)
- 弱三色不变式:黑色可以引用白色,若白色对象被灰色对象(或白色对象链路上层存在灰色对象)引用(破坏条件2)
只要满足强/弱三色不变式之一,即可保证对象不丢失;
根据强/弱三色不变式,衍生了屏障机制:
-
插入屏障不再栈上使用,因为你每次引用对象都要进行判断,首先栈的空间较小,还需要提供日常函数调用,因此需要对性能有要求,因此插入屏障不再栈上使用)
-
具体操作:在A对象引用B对象时,B对象被标记为灰色,满足强三色不变式(不存在黑色对象引用白色对象,因为白色对象全部变为灰色了)
-
缺点:因为栈上不使用插入屏障,所以如果栈上某个黑色对象引用了白色对象,最终白色对象会被丢弃 上面对象9会被丢失
-
解决办法:回收白色对象之前,启动stw,将栈上数据全部变为白色,在进行一次扫描。停止stw,进行清除白色操作 就可以避免对象9丢失 这样stw比较短暂
插入写屏障不足:结束时需要STW重新扫描栈空间;
-
-
删除屏障:还是栈上不使用
-
具体操作:被删除对象,如果自身为灰色或者白色,那么被标记为灰色 满足弱三色不变式(保护灰色对象到白色对象的路径不会断)
-
缺点:回收精度比较低,被删除的对象在下一轮才会被清理掉
-
3. Go V1.8 三色标记法+混合写屏障机制
栈上不使用:
- GC将栈上可达对象全部置黑色(之后不再进行二次扫描,无需STW)
- GC期间,在栈上创建新对象,都是黑色
- 被删除对象置为灰色
- 被添加对象置为灰色
标签:灰色,标记,对象,白色,回收,栈上,STW,GC,垃圾 来源: https://www.cnblogs.com/wustjq/p/16439693.html