GC

三色并发标记-清除垃圾回收器 tricolor concurrent mark-sweep

对象被标记为白灰黑三色

初始情况下,所有的对象都是白色,接着从 goroutine 栈空间和全局变量开始扫描,遇见一个,标记为灰,当一个对象所有引用的都被标记过后,我们将它标记为黑色

标记

停止活动的程序,在依赖图中找到进程依然引用的对象,并标记,未被标记的对象即为已不可访问的垃圾对象

BFS 标记算法: 从有向图(或者链表)的根部节点出发,BFS 标记第一层为黑色,第二层为灰色,然后灰色层还有引用的,继续把灰色涂黑,第三层涂灰,直到找不到新的引用,最后剩下白色的即为我们要清除的

问题:如果并发处理的话,图会不断新增引用,如何防止不会错误清除?

  1. 如果是新的引用对象,涂成灰色
  2. 如果是指针引用的改变:通过在赋值表达式的位置插入涂灰的函数

扫描

初始时所有的元素都是白色,这是 GC 还未开始工作。GC开始的时候所有的根元素都被涂灰,然后每次 GC 开始扫描灰色元素的时候,扫描一个就把它涂黑,然后把它的子节点都涂灰

运行时相关的函数

runtime.SetGCPercent runtime.GC runtime.FreeOSMemory