退出码137表示容器被SIGKILL(信号9)强制终止,主因是OOM Killer触发:若docker inspect显示"OOMKilled": true,则为容器超内存limit被cgroup杀;若为false,则多因宿主机全局OOM或节点MemoryPressure驱逐。

容器会随机崩溃退出,且 docker ps -a 显示状态为 Exited (137) —— 这是 Linux OOM Killer 杀掉进程的铁证,不是应用 bug。
容器启动后秒退或反复重启
典型表现:运行 docker run -d --memory=256m mysql:8.0 后,docker ps 看不到容器,docker logs 为空或只有初始化日志;docker ps -a 显示 Exited (137)。MySQL、Redis、Elasticsearch 等内存敏感服务尤其容易中招。
根本原因不是容器没跑起来,而是内核在启动过程中就因内存不足触发了 OOM Killer——连日志都来不及刷全就被干掉了。
- MySQL 启动时需预分配 buffer pool,默认占物理内存 50%~75%,256MB 容器根本扛不住
- Java 应用即使设了
-Xmx512m,JVM 自身元空间、CodeCache、线程栈等额外开销仍可能突破容器限制 - Spring Boot + Actuator + Prometheus Exporter 组合下,堆外内存(如 Netty 直接缓冲区)常被忽略,极易超限
Docker Desktop 进程(vmmem / Docker Desktop)内存持续飙高
Windows 上任务管理器看到 vmmem 进程长期占用 3GB+,macOS 上 Activity Monitor 中 “Docker Desktop” 内存使用居高不下(>2GB),但 docker stats 显示所有容器 RSS 总和才 800MB —— 这说明瓶颈不在容器层,而在 WSL2 虚拟机本身内存配额太小,导致频繁换页、压缩、回收,反而加剧内存压力。
此时调整单个容器的 --memory 没用,必须先调大 WSL2 底层资源池。
- WSL2 默认会动态占用主机 50% 内存,但最小保留值过低(如 2GB),遇上多个容器并发申请,就会陷入“分配→OOM→回收→再分配”的恶性循环
-
.wslconfig中未设memory,或设得过小(如memory=2GB),会导致整个 WSL2 实例内存紧张,影响所有容器稳定性 - 即使容器设置了
--memory=4g,若 WSL2 总内存只有 3GB,该容器根本无法真正获得 4GB,Docker 会在底层静默降级或直接拒绝启动
连接被拒绝、服务不可达但容器显示运行中
现象:docker ps 显示容器 Up 2 minutes,但 curl http://localhost:8080 返回 Connection refused,docker exec -it xxx netstat -tlnp 查不到监听端口,docker logs 也无报错。
这往往是因为容器进程已因 OOM 被杀,但容器状态未及时刷新(Docker daemon 与 containerd 之间存在短暂延迟),看起来“活着”,实际已僵死。
- 常见于 Node.js、Python Flask/Gunicorn 类服务:主进程被杀后子进程残留,
docker ps仍显示容器 ID,但无有效监听 - Redis 启动后瞬间崩溃,
redis-cli ping超时,docker inspect的State.Status是running,但State.OOMKilled为true(需查 JSON 输出) - 使用
docker stats --no-stream可快速识别 RSS 异常偏低的容器(如长期卡在 2–5MB),大概率已僵死
/dev/shm 空间不足引发的静默失败
容器没崩溃、日志也正常,但 Chrome 无头模式打不开页面、Java NIO DirectByteBuffer 分配失败、或 TensorFlow 数据加载卡住——这些都可能是 /dev/shm 默认 64MB 不够用导致的。
它不触发 OOM Killer,也不写错误码,只是让系统调用返回 ENOMEM 或直接 SIGBUS,应用层往往捕获不到或误判为网络/IO 问题。
- Chrome 启动时需约 512MB
/dev/shm空间用于 GPU 共享内存,--shm-size=2g是稳妥起点 - PostgreSQL 使用
shared_buffers时若配合大容量/dev/shm,可提升 WAL 写入性能,但默认 64MB 会成为瓶颈 -
docker run加了--memory却忘了--shm-size,等于只锁住了主内存,放开了共享内存这个“后门”
真正卡住人的地方,往往不是记不住参数,而是分不清哪一层在喊饿:是容器自己要不够,还是 WSL2 这个“房东”没给够地基,又或是 /dev/shm 这个“工具间”太小导致工人没法干活。三者混在一起时,Exited (137) 就成了最模糊也最危险的提示。











