go垃圾回收

什么时候最适合做垃圾回收?当没有人进行观察时。用一颗摄像头对眼球进行追踪,当对象的眼睛离开屏幕时就执行垃圾回收。 When is the best time to do a GC? When nobody is looking. Using camera to track eye movement when subject looks away do a GC.

-- Richard Hudson

垃圾回收常见算法

引用计数式

追踪回收式

go垃圾回收算法 三色标记法

三色标记算法中,会将对象标记为黑、灰、白三种颜色,白色对象将被回收

并发标记问题

假设某个灰色对象 A 指向白色对象 B, 而此时赋值器并发的将黑色对象 C 指向(ref3)了白色对象 B, 并将灰色对象 A 对白色对象 B 的引用移除(ref2),则在继续扫描的过程中, 白色对象 B 永远不会被标记为黑色对象了(回收器不会重新扫描黑色对象)。 进而产生被错误回收的对象 B。【C就会指向一个非法地址,野指针】

img

也就是说,同时满足以下两个条件就可能出现错误回收非垃圾对象的问题:

  • 条件1:某一黑色对象引用白色对象

  • 条件2:对于某个白色对象,所有和它存在可达关系的灰色对象丢失了访问它的可达路径

并发标记问题解决方案

Stop The World

一种最简单解决三色标记并发问题的方法是停止所有的赋值器线程,保证标记过程不受干扰,即垃圾回收器中常提到的STW, stop the world方法。

读写屏障技术

另外一种思路就是使用赋值器屏障技术使得赋值器在进行指针写操作时同步垃圾回收器,保证不破坏弱三色不变性(屏障技术:给代码操作内存的顺序添加一些限制,即在内存屏障前执行的动作必须先于在你内存屏障后执行的动作

三色不变式

  • 强三色不变性:黑色对象永远不会指向白色对象

  • 弱三色不变性:黑色对象指向的白色对象至少包含一条由灰色对象经过白色对象的可达路径

GO垃圾回收器工作步骤

  • 垃圾回收之前将所有的对象标记为白色

  • 遍历GC Root Set,将可达对象标记为灰色

  • 遍历灰色对象列表,将可达的对象从白色标记为灰色;将遍历完的灰色对象标记为黑色

  • 继续三色标记直至灰色对象队列为空

  • 最后将栈空间和堆空间的白色垃圾对象进行回收

Dijkstra插入写屏障

目的:实现强三色不变性,防止黑色对象指向白色对象。

在垃圾回收器工作过程中,新被添加的对象为白色,但是给堆上黑色对象添加对象,那么被添加的对象由于立即出发插入写屏障会立即被标志为灰色(白色转为灰色),而给栈上黑色对象添加对象则仍然是白色(因为不会触发插入写屏障)

那么对于栈上对象还是可能出现黑色对象指向白色对象,这样不是又可能出现“野指针”情况了吗?所以当三色标记扫描完毕之后,还会启动STW,然后单独对栈上对象进行一次扫描。

为什么不在栈上使用插入写屏障?因为需要保证函数的执行效率,栈空间是有限的而函数地址也是存在于栈上,如果频繁执行插入写屏障就意味着函数栈地址会频繁出入栈,对函数执行效率产生影响。

Yuasa删除写屏障

目的:实现弱三色不变性,防止丢失灰色对象到白色对象的可达路径(就是说允许黑色对象指向白色对象,但是一定存在一条经过灰色对象达到白色对象)。

在垃圾回收器工作过程中,移除对象所引用的的某一对象,那么被移除的对象会被标志为灰色。

这种方式的回收精度低,一个对象即使被删除了最后一个指向它的指针也依旧可以活过这一轮,在下一轮GC中被清理掉。

混合写屏障

插入写屏障短板:结束时需要STW来重新扫描栈,标记栈上引用的白色对象的存活;

删除写屏障短板:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象。

混合写屏障过程:

  • GC开始时将栈上所有对象标记为黑色,无须STW

  • GC期间在栈上创建的新对象均标记为黑色

  • 将被删除的下游对象标记为灰色

  • 将被添加的下游对象标记为灰色

混合写屏障的四种场景

Golang三色标记+混合写屏障GC模式全分析

注意第四个场景,被一个已经发生逃逸的对象所引用那么被引用的对象也会发生逃逸,也就意味着不会存在堆对象引用栈对象的情况发生(因为该栈变量在编译阶段的逃逸分析时就会逃逸到堆上)

这张图是有问题的,原因是堆上对象不可能引用栈上对象,在逃逸分析中我们得知:一个对象被一个已经发生逃逸的对象所引用也会发生逃逸。

go垃圾回收触发时机

Golang什么时候会触发GC

reference

Golang三色标记+混合写屏障GC模式全分析

视频:Golang中GC回收机制三色标记与混合写屏障

图示Golang垃圾回收机制

Go语言GC实现原理及源码分析

第 8 章 垃圾回收

7.2 垃圾收集器

[典藏版]Golang三色标记、混合写屏障GC模式图文全分析

9. 什么是写屏障、混合写屏障,如何实现?

Golang垃圾回收(GC)介绍

深入了解 Go:垃圾回收机制

Golang源码探索(三) GC的实现原理

深度剖析 Golang 的 GC 扫描对象实现

Golang什么时候会触发GC

最后更新于

这有帮助吗?