GC 中 stw 时机,各个阶段是怎么解决的?

Go的垃圾收集器(GC)使用了一个叫做三色标记-清除(Tri-color Mark and Sweep)的算法,其中涉及到了两个主要的阶段:标记(Mark)阶段和清除(Sweep)阶段。在这两个阶段中,有一些阶段需要停止世界(STW,Stop The World),但自从Go 1.5版本以后,Go语言的GC已经做到了几乎完全并发,STW的时间被大大减少。

以下是Go GC中的STW时机和如何解决的:

  1. 开始STW:在开始标记阶段之前,需要进行一次短暂的STW,以确保所有的P(处理器)都停止在安全点,即一个不会修改堆的位置。这个STW时机是必要的,因为它能确保在标记阶段开始时,所有的goroutine都不会创建新的对象或修改现有对象的指针。这个STW的时间通常非常短。

  2. 结束STW:在标记阶段结束后,需要进行一次短暂的STW,以确保所有的goroutine都停止在安全点,然后进行最后一次的标记,并开始清除阶段。这个STW时机也是必要的,因为它能确保在清除阶段开始时,所有的对象都已经被正确地标记。这个STW的时间也通常非常短。

在标记阶段,Go的GC采用了并发标记的策略,即在goroutine运行的同时进行标记。这是通过写屏障(Write Barrier)实现的,写屏障在每次写入指针时都会标记该指针。这样,即使在标记阶段有新的对象被分配或旧的对象被更新,GC也能正确地标记这些对象。

在清除阶段,Go的GC采用了并发清除的策略,即在goroutine运行的同时进行清除。这是通过延迟清除(Lazy Sweeping)实现的,即只在需要分配新的对象时才清除那个对象所在的内存块。

这些策略大大减少了Go GC的STW时间,从而提高了程序的响应性和性能。

发表评论

后才能评论