go垃圾回收
三色标记算法(Go 1.5、Go 1.6)
也叫三色并发标记法
三色标记法是传统 Mark-Sweep 的一个改进,它是一个并发的 GC 算法。
让系统的gc暂停时间能够预测
通过三个阶段确定要清除的对象有哪些
根节点对象:全局变量和函数栈里的对象
原理:
- 首先创建三个集合:白、灰、黑。
- 新创建的对象放入白色集合中。
- 然后从根节点开始遍历所有对象(注意这里并不递归遍历,只遍历一次),把遍历到的对象从白色集合放入灰色集合,(这里放入灰色集合的都是根节点的对象)
- 之后遍历灰色集合,将灰色对象_引用的对象_从白色集合放入灰色集合,之后将此灰色对象放入黑色集合,(这里指的是灰色对象引用到的所有对象,包括灰色节点间接引用的那些对象,没有自节点的,也会被移动到黑色集合当中)
- 重复 上面一部,直到灰色中无任何对象
- 通过write-barrier(写屏障)检测对象有变化,重复以上操作,直到灰色对象中没有对象
- 收集所有白色对象(垃圾),还在白色集合中的意味着已经找不到该对象在哪了,不可能会再被重新引用
一次垃圾回收完成后,将黑色集合变色成白色集合,会进一步gc操作,依此循环
注意:
- 如果没有STW,在标记的时候对象被引用了,会出现对象丢失现象,可以使用写屏障实现类似STW的效果,尽可能地缩短STW的时间
缺陷:
- 垃圾产生的速度会大于垃圾收集的速度,这样会导致程序中的垃圾越来越多无法被收集掉。
二、写屏障
原理:
就是当某一个对象被标黑,此时这个对象又被其他对象引用,就把引用这个对象的对象变灰入队,
比如a对象被标黑,a又被b引用,那就把b标灰
强三色不变性
黑色对象不会指向白色对象,只会指向灰色对象或者黑色对象
弱三色不变性
黑色对象指向的白色对象必须包含一条从灰色对象经由多个白色对象的可达路径
1.插入写屏障(使满足强三色不变性)
.如果两个对象之间新建立引用,那么引用指向的对象就会被标记为灰色以满足强三色不变性
.标记其对应对象为灰色状态,这样就不存在黑色对象引用白色对象的情况了,满足强三色不变式
2.删除写屏障(使满足弱三色不变性)
一个灰色对象指向一个白色对象的引用被删除,那么在删除之前写屏障检测到内存变化,就会把这个白色对象标灰
3.混合屏障
插入写屏障和删除写屏障