直接回答:alloc_space/alloc_objects 统计自进程启动累计分配过的内存(含已回收),回答“哪里在制造垃圾”;inuse_space/inuse_objects 统计当前存活占用,回答“谁在占着内存不放”。定位泄漏与常驻高占用看 inuse,定位 GC 压力与分配热点看 alloc——两者默认采样率不同,不能直接互比绝对值。
展开解析:场景对号入座:内存持续增长怀疑泄漏——采 inuse_space,两次采样(间隔业务周期)做 -base 差分,增长部分对应的栈即嫌疑犯,配合 goroutine profile 看是否泄露的 goroutine 持有引用;RSS 高但 inuse 不高——碎片化或 GC 归还策略问题(Go 1.16+ 默认 MADV_FREE,RSS 滞后于实际释放,用 /debug/pprof 的 heap 与 runtime.MemStats 交叉确认,容器限额场景调 GOMEMLIMIT 主动约束);GC 频繁 CPU 高——看 alloc_space 找制造垃圾最多的栈,优化方向是复用(sync.Pool、buffer 预分配、减少临时对象)。采样机制要懂:heap profile 按分配速率采样(默认每 512KB 一个样本),小对象高频分配可能漏记,绝对值需按采样率缩放(pprof 已处理);获取方式 /debug/pprof/heap 默认 inuse,加 gc=1 参数触发一次 GC 再采样,排除待回收干扰。配套工具:runtime.ReadMemStats 看 HeapAlloc/HeapReleased/NextGC 判断是泄漏还是 GC 目标线问题;pprof 的 peek 与 traces 视图对异常对象类型(某 struct 百万实例)定位最快。
追问方向:为什么容器里 Go 服务常 OOM 于 inuse 远低于限额时?采样率如何调?
(约 480 字)