实现原理
垃圾收集的多个阶段:
清理准备阶段(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的标记工作的目的