Golang的GC
- 高级语言都会有有垃圾回收机制,操作系统里我们学过多种垃圾回收机制,比如标记-清除、标记-移动、分代清理等,golang垃圾回收的基本思路是标记-清除,其代码在runtime包的mgc.go中。
- 常规的八股文里golang的垃圾回收是基于三色扫描、标记和清除垃圾回收机制,其中三色是黑色、白色和灰色,白色是没有引用可回收的空间、黑色是扫描完成不能释放的空间以及灰色是需要继续扫描的空间。其中通过STW以及并发标记降低STW的时间,标记完后通过写屏障以及用mbit标记的空间回收。
- 但大部分情况说的都是一个gc的过程,但我看源码会发现golang的GC其实是按照循环的思路去做的,所以一个循环的开始时清除结束-标记开始-标记结束以及清除这四个步骤,所以会先把上一次没有清理完的做清理。这可能跟我理解的垃圾回收有区别,也是我觉挺好的一种思路。
- GC的写屏障也跟我理解的不太一样,写屏障开始的非常早,按照上面循环的思路,首先先把上一次未完成的空间释放,开始做GC开始的各种准备,准备完后先STW,然后并发标记,然后开启写屏障,标记完成后停止STW,然后进行清理,完成这一轮的GC。
- 写屏障这个东西其实是为了降低STW的过程,后面开启调度后,标记为白色可回收的内存也有可能被饮用,这时候会有两种方式,一种是不允许也就是不支持强依赖白色内存,所以依赖需要新增,一种是可以依赖白色内存但是必须经过grey内存,调度中新增的内存会直接标记为黑色不可回收。