Golang语言的垃圾回收机制是三色标记混合屏障算法,能够不进行stw,能够降低用户的等待时间。
所有的垃圾回收机制都基本只需要对堆内存进行操作,因为栈内存由操作系统进行分配和释放,不需要程序员的关心。
三色标记
这个动图是三色标记算法的基本过程:在开始的时候,会将所有节点标记为白色;然后从根节点开始遍历,将能够到达的白色引用标记为灰色;然后通过灰色节点再次向下一个节点开始遍历,同时所有标为灰色的节点全都标记为黑色;循环上一步骤,直到灰色标记的集合为空。
这时候所有黑色的节点就视为可使用的,所有的白色的节点就是不可达的对象,作为垃圾清理掉。
这是一个动态的过程,如果在进行标记的过程中,出现了标记的新增、断开或者改变的话,就有可能造成最终的结果出现有垃圾没有完全回收,或者将需要使用的对象作为垃圾释放掉了内存,如果出现的是一个对象漏掉了,没有被清理的话,那么相对来说就会增加内存压力,在下次进行内存回收的时候就可以处理掉,但如果是一个需要被引用的对象被释放掉的话,就会使整个逻辑出现错误,影响是很大的。
屏障
为了解决上述问题,其中一种方案是使用stw,但是stw需要整个业务停滞,浪费了很多时间,所以Golang使用了写屏障来进行处理,能够让在执行垃圾处理的时候不影响业务的执行。
在处理这种情况的时候,屏障会保护被断开的节点,遍历的时候会接着从E节点往下遍历,这样会造成部分的内存浪费,但是这一部分垃圾肯定会扛不住下一轮的垃圾清理。
出现这种情况的时候,因为一个白色标记被黑色给引用了,就会导致白色的标记一直无法被遍历到,这时候屏障就会保护这个被重新引用的白色标记,将G节点变为灰色,这样就不会产生被错误清理的情况了,保证了安全性。整个过程中都不需要STW,也保证了整个过程的效率。