GC(Garbage Collection)
一种内存管理机制,
- STW(Stop the word) GC期间某个阶段会停止所有赋值器,中断你的程序逻辑,
- Root对象
根对象是指赋值器不需要通过其他i对象就可以直接访问的对象,通过Root对象,可以追踪到其他的存活对象。常见的root对象有
- 全局变量 程序在编译器就能确定的那些存在于程序整个生命周期的对象
- 执行栈 每个goroutinue都拥有自已 的执行栈,这些执行栈上包含栈上的变量及堆内存指针。
- 全局变量 程序在编译器就能确定的那些存在于程序整个生命周期的对象
三色标记法
1 初始化所有的对象被标记为白色 2.GC开始,遍历rootset,将直接可达的对象标记为灰色3.遍历灰色对象,将直接可达对象标记为灰色,并将自身标记为灰色4.重复第三步骤,直到标记完所有对象5.将标记为白色的对象当作垃圾回收掉
在标记的过程中,如果同时出现了下面的条件,i对象有可能丢失
- 白色对象被黑色对象引用
- 灰色对象与白色对象之间的可达关系遭到破坏 黑色对象说明这个对象已经被扫描过,被引用的白色对象则不会再被扫描,灰色和白色的关系被破坏后,白色对象就不会扫描。
为了解决上述 的问题,所以就提出了两种破坏条件的方式
- 强三色不变式 不允许黑色对象引用白色对象,破坏了第一个条件,如果黑色不会引用白色对象,那么白色对象就不会扫描不到,从而被被当作垃圾回收掉
- 弱三色不变式 黑色对象可以引用白色对象,但是白色对象的上游必须存在灰色对象,由于有灰色i对象的引用,这个白色i对象一定会被扫描到。
屏障机制 为了遵循上述的原则,提出了两种实现机制:插入写屏障和删除写屏障 插入写屏障 当一个黑色对象引用另外一个对象时,将另外一个对象标记为灰色 插入写屏障只会在堆内存中生效,不会对栈内存生效,但是栈上的对象没有插入写机制,在扫描完成后,仍然可能存在黑色i对象引用白色对象,所以在一次正常的三次标记完成后,需要对栈上重新进行一次stw,然后再rescan一次。
删除写屏障 对象被删除引用时,如果被删除引用的i对象自身为灰色或 白色,那么被标记为灰色。 满足了弱三色不变式。灰色对象到白色对象的路径不会断 一个对象的引用被删除后,由于被引用的对象被标记成灰色,所以会存活,如此一来对象会存活很多轮,会产生 很多的冗余扫描成本,且降低了扫描的精度,回收精度低。
混合写屏障 混合写屏障结合了插入写屏障和删除写屏障的优点
- GCi刚开始的时候,会将栈上的可达对象全部标为黑色
- GC期间,任何在栈上的新创建的对象均为黑色 将栈上的可达对象全部标记为黑色,无需最后对栈进行STW,就可以保证栈上的对象不会丢失, 如果栈 上的对象引用了堆上的对象,那么不会触发混合写屏障
- 堆上被删除的对象标为灰色
- 堆上新添加 的对象标记为灰色