首页/云/云与容器速查/容器 OOMKilled 排查

容器 OOMKilled 排查

容器被 cgroup 内存上限杀死:docker inspect 的 State.OOMKilled=true、退出码 137。要区分『容器限制太小』还是『应用内存真的涨了』,再决定调限还是修代码。

云与容器速查云更新于 2026-10-13

容器 OOMKilled 是什么

容器 OOMKilled 表示容器内进程的内存用量超过了 cgroup 上限,被内核直接杀死,典型表现是退出码 137 且 State.OOMKilled 为 true。关键在于区分两类原因:一类是限制值低于业务的真实需求,属于配置问题;另一类是应用内存持续增长,属于代码或缓存问题。两者的处置方向完全不同。

基本信息

确认方式docker inspect -f 取 State.OOMKilled 得到 true
查看限制HostConfig.Memory 是生效的内存上限
查看用量docker stats 看实时用量,历史曲线看监控系统
内核记录dmesg 中能看到宿主级别的 OOM 与被杀进程记录
两类原因限制低于需求(配置)与内存泄漏或缓存膨胀(应用)

典型使用场景

  • 容器反复重启:确认是否每次都是内存超限被杀
  • 发布后异常:新版本内存占用明显上升,怀疑引入泄漏
  • 并发提升后崩溃:并发数提高导致内存线性上涨并撞上限
  • 容量评估:用稳定运行时的峰值内存决定合理的上限值
  • 宿主告警:容器未设限,把宿主内存吃满引发连锁故障

排查命令

排查命令
docker inspect myapp -f 'OOM={{.State.OOMKilled}} limit={{.HostConfig.Memory}}'
# 上限为 0 表示未设限,容器可一直吃到宿主内存
docker stats --no-stream myapp             # 看当前内存用量与占比
dmesg -T | grep -i "oom\|killed process" | tail -10   # 内核侧记录
free -m                                    # 先确认宿主还有多少余量

原因判定对照

现象判定处置方向
运行一段时间后稳定被杀内存缓慢增长排查泄漏,配合监控看长期曲线
一起量就立刻被杀限制值明显低于需求结合峰值重新设定上限
并发升高时被杀并发与内存正相关限制并发或按并发估算容量
多个容器同时被杀宿主内存不足检查宿主整体内存与超卖情况
调大限制之前先看宿主余量:把容器上限调大只是把风险转移给宿主,宿主级别的 OOM 会杀掉更关键的进程,影响面反而更大。
JVM 类应用要特别注意堆外内存:堆、元空间、线程栈、直接内存加起来可能远超设定的堆上限,只按堆大小估算容器内存限制会持续踩坑。

易错点

  • 只看容器不看宿主,宿主内存紧张时容器同样被杀,原因却不在容器
  • Java 应用只按堆上限估算容器限制,堆外内存把容器撑爆
  • 看到 137 就断定是 OOM,实际也可能是被人工或者编排系统杀死
  • 无限重启当作临时方案,每次重启都丢一次现场,根因始终查不出来

数据来源与参考

  • Docker Docs:Resource constraints
  • Linux cgroup v2 文档(memory)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌