Golang中的GC(上)

507 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

Golang作为高级语言它内部会自行的GC(垃圾回收)。如果我们能够更好的了解GC的策略,这对于我们开发过程中对于内存的合理使用是非常有帮助的,我们在不同的版本提供了不同的GC算法:
1.3之前:标记清除算法(mark and sweep)
1.5: 三色标记算法
1.8: 三色标记+混合写屏障
今天这篇文章我们一起来探讨这三种不同的GC算法以及他们的优缺点

标记清除算法

  • 标记 在这里插入图片描述 如上图所示,当程序开始GC时会先标记可达对象(也就是有引用指向的对象)。经过标记后图中的红色对象保留

  • 清除 经过上一轮的标记后,我们发现对象5是没有引用指向的,所以对象5会在这一轮GC中被清除

缺点:

  1. 会产生STW 标记清除算法有个问题时,在整个标记清除阶段程序会进入STW(Stop the World)。STW过程中,Golang调度器阻塞,也就是不会执行任何用户代码,整个应用程序阻塞。标记清除的STW如下如所示

在这里插入图片描述 2. 标记阶段需要扫描整个堆(性能较差)
3. 容易产生内存碎片

三色标记算法

三色标记发采用逻辑上的黑、灰和白三种颜色来标记对象。GC和用户协程可以异步执行,在一定程序上减少了STW的时间。

STEP1

在这里插入图片描述

如上图所示,三色标记法的第一步会将所有的对象都标记成白色

STEP2

在这里插入图片描述

第二步会遍历Root Set(Golang的对象管理集合)第一层(不会进行递归遍历),取到可达对象Object1,Object4。将这两个对象放入灰色标记表

STEP3

在这里插入图片描述

本次会扫描灰色表中的Object1,Object4对象,将这两对象的下一层可达对象放入灰色标记表中,然后将这两对象放入黑色标记表中。经过这一轮后,Object1、Object4被放入黑色标记表。Object2被放入灰色标记表

STEP4

在这里插入图片描述 重复STEP2和STEP3,将灰色表中的对象全部搬移至黑色标记表时,整个三色标记法结束。白色标记表中剩下的对象就是此次GC要清除的对象。

以上是整个三色标记法的流程,很明显在开始标记时STW就会开始,然后当确定白色标记表中的对象时,STW就会结束。到目前为止也没用看出三色标记法有多高效。

后续文章我们继续探讨,Golang为了提高GC效率所采用的强/弱三色标记算法,以及三色标记+混合写屏障