GC 触发有三条路径:堆增长到目标值时自动触发——目标堆大小 = 上次 GC 后存活堆 × (1 + GOGC/100),GOGC 默认 100,即堆翻倍触发;runtime.GC() 手动触发;以及系统辅助(长时间未 GC 时强制触发,约 2 分钟一次)。
调优工具:GOGC 控制 GC 频率与内存占用的权衡——调大减少 GC 次数但占用更多内存,调小反之;设为 off 可关闭自动 GC(需配合 GOMEMLIMIT 防 OOM)。Go 1.19 引入 GOMEMLIMIT 设置内存软上限,当内存接近上限时 GC 会更激进,能防止容器内 OOM Kill,是容器部署的推荐配置。还有一个隐式成本:GC 辅助(mutator assist)会让分配过快的 goroutine 帮忙做标记,抢占业务 CPU。
debug.SetGCPercent(50) // 等价 GOGC=50
debug.SetMemoryLimit(4 << 30) // 等价 GOMEMLIMIT=4GiB
易错点:GOMEMLIMIT 是软限制,包含所有运行时内存,设小了会导致 GC 抖动(thrashing);不要盲目调 GOGC,先用 gctrace 确认 GC 真是瓶颈。追问方向:GC pacing 的目标函数、ballast 内存球的利弊。