实现原理

垃圾收集的多个阶段:

清理准备阶段(STW)
  • 暂停程序,所有的处理器在这时会进入安全点

我的理解是这里stw,等待所有协程都知道要开始打开写屏障了,不然无法做到统一

  • 如果当前垃圾收集循环是强制触发的,我们还需要处理还未被清理的内存管理单元
标记阶段-并发执行
_GCmark
标记终止阶段 -STW
_GCmarktermination
清理阶段-并发执行
_GCoff

触发时机

主动触发

被动触发

  • 默认2min没有触发过GC,则触发一次GC

  • 分配内存时,若内存分配达到一定比例则触发

GC对CPU的使用率

在GC准备阶段,go语言给每个P创建一个mark worker协程(就是标记的协程),把对应的g指针存储到p中,这些mark worker创建后很快陷入休眠,等到标记阶段得到调度执行

GC默认的CPU目标使用率为25%

GC在mark worker中引入了三种不同的工作模式:

gcMarkWorkerFractionalMode
gcMarkWorkerDedicatedMode
gcMarkWorkerIdleMode

三种不同模式的工作协程会相互协同保证垃圾收集的 CPU 利用率达到期望的阈值

标记辅助

用户程序有可能在GC期间分配新的内存,为了保证用户程序分配内存的速度不会超出后台任务的标记速度,运行引入了标记辅助技术。

gcAssistBytes

如果是,会暂停分配内存过快的哪些goroutine,并将其转去执行一些辅助标记的工作,从而达到放缓继续分配、辅助GC的标记工作的目的

参考资料