Golang GC 过程
一、GC过程
Golang 1.5后,采取的是“非分代的、非移动的、并发的、三色的”标记清除垃圾回收算法。
Golang的GC过程如下所示(图片来自:https://talks.golang.org/2015/go-gc.pdf):
一共分为四个阶段:
1. 栈扫描(开始时STW)
2. 第一次标记(并发)
3. 第二次标记(STW)
4. 清除(并发)
二、三色标记原理
整个进程空间里申请每个对象占据的内存可以视为一个图, 初始状态下每个内存对象都是白色标记。
1. 先STW,做一些准备工作,比如 enable write barrier。然后取消STW,将扫描任务作为多个并发的goroutine立即入队给调度器,进而被CPU处理
2. 第一轮先扫描root对象,包括全局指针和 goroutine 栈上的指针,标记为灰色放入队列
3. 第二轮将第一步队列中的对象引用的对象置为灰色加入队列,一个对象引用的所有对象都置灰并加入队列后,这个对象才能置为黑色并从队列之中取出。循环往复,最后队列为空时,整个图剩下的白色内存空间即不可到达的对象,即没有被引用的对象;
4. 第三轮再次STW,将第二轮过程中新增对象申请的内存进行标记(灰色),这里使用了write barrier(写屏障)去记录