为了压 GC 停顿把 GOGC 从 100 调到 800,P99 从 90 毫秒降到 40 毫秒,第二天监控显示 CPU 多了三成,容器内存逼近上限被杀,回滚配置后延迟又弹回原值。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,GOGC 放大的是两次回收之间的堆增长比例,堆翻几倍才触发一次,回收次数少了但每次要扫的对象更多,堆峰值和标记阶段的 CPU 一起上去,拿内存换延迟的账要算清楚。
「GOGC 参数取舍」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。报错里带路径的,先去看那个路径在不在、权限对不对。
GODEBUG=gctrace=1 ./app GOGC=400 GOMEMLIMIT=3GiB ./app go tool pprof http://localhost:6060/debug/pprof/heap
同一份配置存在多处的,先确认改的是被加载的那一份。
具体做法是,先看回收日志里的触发频率和堆峰值的整体变化;用内存上限参数把最坏的情况先兜住再谈延迟;回收比例一次调小一档并且盯着延迟分位一起看。
最后用这个标准收尾,P99 保持在 60 毫秒内,堆峰值和 CPU 占用回到调参前的水平,不再被系统杀掉。
