Docker容器为何总是被终止?未设资源限制却报137错误码
嘿,这个问题我之前排查过好多次,错误码137在Docker场景下几乎等同于进程被系统的OOM Killer(内存不足杀手)强制终止,哪怕你没给容器单独设置资源限制也会出现这种情况,具体原因和解决办法我给你梳理下:
1. 宿主机整体内存耗尽
虽然你没有给容器设置内存上限,但如果宿主机本身的剩余可用内存已经被榨干,Linux内核的OOM Killer会自动挑选内存占用高的进程(比如你的SpringBoot Java应用)优先杀掉,来释放内存给系统续命。
你可以通过以下命令确认:
- 查看宿主机内存使用情况:
free -h - 检查OOM Killer的日志记录:
dmesg | grep -i oom,如果能看到类似Out of memory: Killed process <PID> (java)的日志,就实锤是这个原因了。
2. Java进程的内存配置不合理
SpringBoot应用默认的JVM堆内存设置可能没有适配你的环境,Java进程会根据宿主机内存自动调整堆大小,如果你的应用内存需求较高,或者宿主机本身内存不大,JVM尝试占用的内存就可能触发系统的OOM机制。
解决办法是启动容器时手动指定JVM内存参数,比如限制堆内存为512M:
docker run -e JAVA_OPTS="-Xmx512m -Xms256m" api:latest
根据你的应用实际内存需求调整Xmx(最大堆内存)和Xms(初始堆内存)的值。
3. Docker守护进程的总内存限制
如果你是在Docker Desktop(Windows/Mac)环境下运行,Docker默认会给整个Docker环境分配有限的内存(比如默认2GB),如果同时运行了其他容器,总内存占用超过这个限制,也会触发OOM Killer杀掉占用高的容器进程。
你可以打开Docker Desktop的设置界面,找到“Resources”选项,调整分配给Docker的内存大小,比如改成4GB,再重新运行容器试试。
快速验证方法
你可以先给容器设置一个明确的内存上限,看看能不能正常运行:
docker run --memory=1g api:latest
如果容器能稳定运行不退出,就说明确实是内存不足导致的问题,再根据上面的思路逐步优化内存配置即可。
内容的提问来源于stack exchange,提问作者Jakim

