凌晨告警里,一个设置为1GiB的容器突然被重启,监控只显示“内存使用率99%”。管理员既怀疑业务存在内存泄漏,也怀疑是宿主机上其他容器抢占资源,还有人认为只是Linux缓存没有及时释放。真正有用的证据,不会藏在单一的使用率曲线里,而要结合cgroup内存水位、内存回收压力、PSI内存指标以及OOM事件记录逐层确认。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:hhost(海外服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
先读懂容器内存水位:超限不是“RSS到顶”
cgroup v2中,memory.current是容器当前计入限制的内存总量,除了进程匿名页,还可能包含文件缓存;memory.max才是硬上限。RSS或容器面板显示的“已用内存”,通常不能直接等同两者。排查时先在同一层级读取memory.current、memory.max、memory.stat和memory.events,并确认进程是否位于正确的cgroup,避免把宿主机总内存当成容器额度。
判断程序泄漏,要重点观察匿名内存是否持续增长,以及回收后能否降下来。文件缓存增长、回收后明显回落,通常更像正常缓存波动;若anon持续上涨、file几乎不变且memory.events中的oom_kill不断增加,才更像泄漏或无界分配。memory.events里的high、max只说明压力或上限被触及,不能单独证明发生了OOM。

再用回收、交换与OOM证据区分三类故障
第一步看内存回收压力。若memory.stat中的anon不断上升,回收无法释放匿名页,说明进程可能持有对象或内存泄漏;若file持续下降、anon基本稳定,容器更可能只是缓存膨胀。第二步看交换抖动:宿主机vmstat中的si、so持续升高,同时PSI的some和full明显不为零,代表系统频繁换入换出;这时即使容器还没到自身上限,也可能因延迟和抖动被判定为异常。
第三步核对容器内存上限与OOM记录。若memory.current逼近memory.max,memory.events出现max,随后又有oom_kill,且内核日志或容器运行时事件显示对应进程被杀,基本可判定为限制触发。若容器自身水位不高,但宿主机PSI升高、free内存很少且其他cgroup也在增长,则应转向宿主机争用方向。把“容器被杀”和“宿主机内存紧张”混为一谈,会把限额调大当成根治。
实战中可用ServLlama汇总容器水位、回收和PSI趋势,保留异常前后的快照,再按“水位→回收→交换→事件”的顺序复核。常见踩坑是只看某一时刻的百分比,或者在OOM后立即重启进程,却没有保存memory.events、PSI和内核日志;这些证据一旦丢失,就很难证明究竟是泄漏、限额触发还是宿主机争用。

从水位线判断回收压力
cgroup内存水位不是单一阈值:在 cgroup v2 中,memory.high 是柔性线,越过它会触发缓存回收和节流,但不立即终止进程;memory.max 才是硬性的容器内存上限。无法继续回收时才可能 OOM,因此“接近上限”不能直接判定故障。
PSI内存指标中,some 表示部分任务因内存不足停顿,full 表示所有非空闲任务同时停顿。采样宿主机 /proc/pressure/memory 与目标 cgroup 的 memory.pressure,记录 avg10、avg60、avg300 和 total;若持续升高并与业务延迟同步,才说明内存回收压力已形成。
回收顺序也会误导排查:内核通常先清页缓存、dentry 和 inode,匿名页不能像文件缓存一样直接丢弃,mmap 业务还可能出现缺页延迟。对照 memory.stat 的 anon、file、slab、pgscan,可区分匿名内存膨胀、缓存堆积和内核对象占用。
OOM 判断必须落到目标 cgroup。检查 memory.events 中 high、max、oom、oom_kill 的累计值,并用 memory.peak 对照历史峰值;宿主机日志只能辅助,不能替代OOM事件记录。

常见误区与可执行检查清单
常见坑是只看宿主机 free、只查 dmesg,或把 swap 当安全阀。前者会漏掉 cgroup 限额,OOM 也可能发生在别的 cgroup;swap 可能扩大延迟,应同时核对 memory.swap.current、memory.swap.max 与内存事件。
可执行检查清单:①确认 cgroup 版本、路径和上限;②比较 memory.current、memory.peak;③查看 memory.events 是否增长;④采样 /proc/pressure/memory、memory.stat 和进程 RSS;⑤关联容器日志、宿主机日志与业务延迟;⑥异常退出时核对 oom_kill、PID 和应用日志;⑦先限速或扩容,再调缓存、堆与并发。
结论应按“越过水位出现回收停顿触发 OOM”逐层验证:PSI 确认压力,memory.stat 定位构成,memory.events 定性并保留现场,才能区分缓存波动、瞬时峰值与真正的内存泄漏。


喜欢
顶
难过
囧
围观
无聊





