文章目录
- GoLang之GC垃圾回收
GoLang之GC垃圾回收
1.前言
2.Go V1.3之前的标记-清除(mark and sweep)算法
3.标记-清扫(mark and sweep)的缺点
4.Go V1.5的三色并发标记法
5.没有STW的三色标记法
6.屏障机制
6.1 “强-弱” 三色不变式
6.2插入屏障
添加下游对象(当前下游对象slot, 新下游对象ptr) {
//1
标记灰色(新下游对象ptr)
//2
当前下游对象slot = 新下游对象ptr
}
A.添加下游对象(nil, B) //A 之前没有下游, 新添加一个下游对象B, B被标记为灰色
A.添加下游对象(C, B) //A 将下游对象C 更换为B, B被标记为灰色
6.3删除屏障
添加下游对象(当前下游对象slot, 新下游对象ptr) {
//1
if (当前下游对象slot是灰色 || 当前下游对象slot是白色) {
标记灰色(当前下游对象slot) //slot为被删除对象, 标记为灰色
}
//2
当前下游对象slot = 新下游对象ptr
}
A.添加下游对象(B, nil) //A对象,删除B对象的引用。 B被A删除,被标记为灰(如果B之前为白)
A.添加下游对象(B, C) //A对象,更换下游B变成C。 B被A删除,被标记为灰(如果B之前为白)
7.Go V1.8的混合写屏障(hybrid write barrier)机制
7.1插入写屏障和删除写屏障的短板
7.2混合写屏障规则
添加下游对象(当前下游对象slot, 新下游对象ptr) {
//1
标记灰色(当前下游对象slot) //只要当前下游对象被移走,就标记灰色
//2
标记灰色(新下游对象ptr)
//3
当前下游对象slot = 新下游对象ptr
}
7.3混合写屏障的具体场景分析
GC开始:扫描栈区,将可达对象全部标记为黑
场景一: 对象被一个堆对象删除引用,成为栈对象的下游
//前提:堆对象4->对象7 = 对象7; //对象7 被 对象4引用
栈对象1->对象7 = 堆对象7; //将堆对象7 挂在 栈对象1 下游
堆对象4->对象7 = null; //对象4 删除引用 对象7
场景二: 对象被一个栈对象删除引用,成为另一个栈对象的下游
new 栈对象9;
对象8->对象3 = 对象3; //将栈对象3 挂在 栈对象9 下游
对象2->对象3 = null; //对象2 删除引用 对象3
场景三:对象被一个堆对象删除引用,成为另一个堆对象的下游
堆对象10->对象7 = 堆对象7; //将堆对象7 挂在 堆对象10 下游
堆对象4->对象7 = null; //对象4 删除引用 对象7
场景四:对象从一个栈对象删除引用,成为另一个堆对象的下游
堆对象10->对象7 = 堆对象7; //将堆对象7 挂在 堆对象10 下游
堆对象4->对象7 = null; //对象4 删除引用 对象7