垃圾回收简称GC,是释放那些不再被使用的内存空间的过程。换句话说,垃圾回收器会去检查哪些对象超出范围并且不会再被引用到,然后它会去释放那些对象占用的内存空间。
Golang从1.5版本开始,用于判断是否可回收对象的方法是三色标记法。那三色标记法到底是什么呢?本文只聚焦三色标记法,其他关于Golang垃圾回收的知识点不在此篇文章范围内。
我们假设有一个Go程序,它的内存情况如下:程序RootSet根节点关联着对象1和对象4,而对象1关联对象2,对象2关联对象3,对象7引用着对象2;另一个分支,对象4引用对象5;对象6处于游离状态。下图展示的就是以上所表述的内存情况,从可达性分析得到,GC应该回收对象6与对象7,那么三色标记法如何识别到对象6和对象7呢?
三色标记法是用于寻找从程序RootSet所关联的对象出发,只遍历一次,为每一个对象标记颜色。标记结束后,被标记为白色的对象需要释放空间,而被标记为黑色的对象继续保留。一次三色标记法结束后,是不存在被标记为灰色的对象的。
如图下所示,第一步我们把所有的对象都标记为白色。

第二步,把在程序根结点集合RootSet里的对象标记为灰色。如下图所示,标记为灰色的是对象1和对象4。

第三步,遍历标记为灰色的对象,找到关联的对象,并标记为灰色,同时把自己标记为黑色。如下图所示,遍历灰色对象发现:对象1关联对象2,对象4关联对象5。那么,把对象2和对象5标记为灰色,同时对象1和对象4标记为黑色。

此时,被标记为灰色的对象是对象2和对象5。第四步,重复第三步,遍历寻找灰色对象所关联的对象,并标记为灰色。如下图所示,对象2关联对象3,对象5没有关联对象。那么把对象3标记为灰色,对象2和对象4标记为黑色。

到了这一步,还剩对象3,对象6和对象7没处理。我们继续,第五步,我们发现对象3没有关联对象,那么如下图,把对象3标记为黑色。

终于把全部对象标记颜色,此时释放被标记为白色的对象的内存空间,保留被标记为黑色的对象,已经不存在被标记为灰色的对象了。
晚安~