三色标记法(Tri-color Marking)
三色标记法是现代垃圾回收(GC)算法中的一种标记清除算法,它主要用于解决并发垃圾回收中的对象标记问题。Go 的垃圾回收机制(GC)在底层就是基于这个算法进行内存管理的。
三色标记法的基本思想:
三色标记法通过将对象分为三种颜色来描述它们的状态,进而实现并发的垃圾回收。这三种颜色分别是:
-
白色(White):表示这些对象尚未被标记,需要被回收。
-
灰色(Gray):表示这些对象已被标记,但它的引用对象还没有被检查过。
-
黑色(Black):表示这些对象已被标记且它们的所有引用对象也已经被检查过。
三色标记法的目标是在垃圾回收过程中避免引发并发修改的问题,同时确保不丢失任何引用或导致内存泄漏。
三色标记法的流程:
-
初始标记:垃圾回收会遍历所有根对象(如全局变量、栈变量、寄存器中的指针等),将它们标记为灰色。
-
灰色对象的处理:
-
遍历灰色对象并将它们的引用对象(即灰色对象指向的对象)标记为灰色。
-
将已经扫描过的灰色对象标记为黑色,表示这些对象及其引用对象已被完全检查。
-
-
清理阶段:
-
最后,白色对象会被视为垃圾对象,进行回收,释放它们所占的内存。
-
具体流程:
-
初始化:
-
将所有根对象标记为灰色。
-
其他所有对象标记为白色。
-
-
灰色队列扫描:
-
从灰色队列中取出一个对象(此对象已经被标记为灰色)。
-
遍历该对象引用的其他对象,并将这些被引用的对象标记为灰色(如果尚未标记)。
-
将当前扫描的对象标记为黑色,表示它已经被完全扫描过。
-
-
清理:
-
遍历堆中所有对象,任何没有被标记为黑色的对象(即仍为白色的对象)都会被视为垃圾并回收。
-
Go 中的垃圾回收与三色标记法:
Go 使用了类似于三色标记法的并发垃圾回收算法,但它使用的是一种更高效的三色标记法的变种,称为 “三色标记并发垃圾回收”(Concurrent Garbage Collection)。Go GC 算法在标记阶段执行并发标记,以避免停止世界的时间过长。
Go 中的垃圾回收与三色标记法:
Go 的垃圾回收机制采用了 “标记-清除” 算法(Mark-Sweep)结合三色标记法。它是一个 分代回收(Generational GC)和 并发回收 的结合体。Go 使用三色标记法来保证并发环境下的正确性,尤其是在没有暂停世界的情况下进行回收。
标记清除的流程:
-
初始化阶段:首先标记所有根对象,并将它们标记为灰色。根对象包括全局变量、栈上的局部变量、以及寄存器中的指针等。
-
并发标记阶段:
-
将灰色对象入队,开始并发扫描灰色对象。
-
遍历灰色对象,并将它们引用的对象标记为灰色,并将已扫描过的灰色对象标记为黑色。
-
-
回收阶段:
-
当垃圾回收标记完所有对象后,回收所有仍然为白色的对象。
-
Go 中三色标记法的优化
在 Go 语言中,垃圾回收器(GC)从 Go 1.5 版本开始采用并发标记的方式,解决了传统 GC 在并发下停顿时间长的问题。Go 在三色标记法的基础上进一步优化了并发标记阶段和清除阶段,减少了对主程序的影响。
Go 1.5 及之前的版本:
-
在 Go 1.5 之前,垃圾回收是完全停止世界(Stop-the-World)的,每次垃圾回收时程序都会暂停,进行垃圾回收操作。这种方式虽然简单,但是对实时性要求高的程序影响较大。
Go 1.5 及之后的版本:
-
从 Go 1.5 开始,引入了 并发标记和并发清除,允许 GC 和应用程序并行运行。通过引入并发标记,Go 可以在程序执行时并发地进行标记,而不需要完全停顿整个程序。
-
Go 1.5 引入了 三色标记法,确保并发标记时没有出现丢失对象或重复标记的问题。
不同 Go 版本之间的差异
Go 在不同版本中对垃圾回收的优化不断增强,尤其是在 并发标记 和 停止世界(Stop-the-World)的时长方面。
-
Go 1.4 及之前:
-
使用传统的 停止世界 算法,垃圾回收会暂停程序,进行全停顿。
-
GC 主要通过标记-清除(Mark-Sweep)和分代收集方式进行。
-
-
Go 1.5:
-
引入了 并发标记 和 并发清除,减少了 GC 停顿时间,避免了全停顿的问题。
-
增加了三色标记法,保证了并发环境中的正确性。
-
-
Go 1.6 - Go 1.10:
-
继续优化 GC 的并发性,减少了垃圾回收的停顿时间。
-
在 Go 1.9 中,GC 停顿时间已大幅缩短到毫秒级,优化了内存管理效率。
-
-
Go 1.11 及之后:
-
Go 1.11 进一步优化了内存回收算法,引入了 三色标记法 的变种来减少内存碎片,并提升了吞吐量和延迟。
-
GC 的并发度进一步提高,减少了 GC 对主程序的影响。
-
-
Go 1.13 及之后:
-
引入了 增量并发标记,使得标记阶段变得更加精细,避免了高并发场景下的标记过程对系统的影响。
-
改进了垃圾回收器的调度和内存分配策略,进一步减少了内存的碎片化。
-
三色标记法的优势:
-
并发性:通过并发标记,垃圾回收的工作可以和应用程序并行进行,从而显著减少 GC 的停顿时间。
-
精确性:三色标记法确保了在并发环境下的标记过程不丢失任何对象,也不会重复标记,保证了垃圾回收的正确性。
-
内存管理:它可以更高效地回收不再使用的对象,避免内存泄漏,并减少内存碎片。
总结:
-
三色标记法 是垃圾回收算法中的一种高效的标记方式,它通过将对象分为白色、灰色、黑色来区分对象的状态,从而确保并发环境下的内存管理。
-
Go 从 1.5 版本 开始采用三色标记法,并结合并发标记和清理,避免了传统 GC 的停止世界问题,使得 GC 停顿时间大大减少,应用程序性能得到了提升。
-
不同的 Go 版本不断优化 GC 的并发性和效率,尤其是在 Go 1.11 和之后的版本,GC 变得更加高效和精细。