GC 目标
- Low Latency 低延迟
- 避免 STW (Stop The World)
- Throughput
- 降低GC占有的CPU周期
- Low Memory footprint 有效内存利用
- Defragmentation 避免内存碎片化, 也是其中一个目标
三者目标是矛盾的
GC 策略
- reference counting
问题:
- 对象大小膨胀
- 造成 cache miss
- 必须是原子操作, 造成多线程锁的争用
- 互引用的问题
- tracing garbage collectors
- mutators 应用程序, 造成无用内存; collector(s) 回收器, 回收整理内存
- naive mark-and-sweep
- 会造成STW
- tri-color marking
- collector(s) 可以和 mutators 并行
- 需要 mutators 保证黑色对象不指向白色对象
- generational
- 基于对内存使用观察: 绝大部分对象的存活时间很短
- 按照对象存活时间分成新生代, 和老生代, 采用不同的策略
tri-color marking 详解:
- 对象通过引用关系, 构建起一个有向图
- 每个节点白/灰/黑
- collector
- mark phase 标记内存
- 从根节点开始, 也就是目前有用的对象, 置灰
- 对一个灰色节点, 将其置黑, 并将其所指向的白色节点置灰
- 剩下的白色节点是可以被回收的
- 灰色节点是白色以及黑色节点间的屏障
- sweep phase 回收无用内存(白色节点)
- mark phase 标记内存
- mutator 保证黑色节点不能指向白色节点
- 如果指向了一个白色节点, 将其标记为灰色, 从而触发 collector 的标记 (monitor whether the mark phase is active and if so perform some write barrier work when mutating pointers)
- 偶尔会被检查栈空间, 从而检索可用对象 (occasionally be asked to suspend and scan its stack)
GOGC参数
- 当新分配的内存大小 / 上次GC存活的内存大小 超过这个阈值时, 触发GC,
- 默认100: 内存占用翻倍时, 触发GC
- 内存占用 VS GC时间
Golang GC 更新记录
- 1.4 STW (Stop the World)
- 1.5 CGC (Concurrenct GC)
- non-generational, non-moving, concurrenct, tri-color, mark and sweep collector
- 保证 GC time < 10 / 50 ms
- 1.6 的目标是 throughput
- bump pointer allocation
- generational copy collector for nursery spaces