Systemd 服务退出码 137 是什么意思如何优化内存限制

文章导读
Systemd 服务退出码 137 表示进程收到 SIGKILL 信号(信号编号 9),通常由 Linux 内核 OOM Killer 因内存不足强制终止进程导致。处理方向应优先排查系统内存水位和 OOM 日志,而非修改应用代码,风险边界在于 swap 扩容仅能缓解崩溃不能提升性能。
📋 目录
  1. 一 命令速用版
  2. 二 为什么会这样
  3. 三 分步处理
  4. 四 怎么验证是否生效
  5. 五 常见坑
  6. 六 常见问题
  7. 七 参考来源
A A

Systemd 服务退出码 137 表示进程收到 SIGKILL 信号(信号编号 9),通常由 Linux 内核 OOM Killer 因内存不足强制终止进程导致。处理方向应优先排查系统内存水位和 OOM 日志,而非修改应用代码,风险边界在于 swap 扩容仅能缓解崩溃不能提升性能。

先说结论:退出码 137 是操作系统内核强制杀死进程的信号编码,绝大多数情况意味着内存不足(OOM),而非程序逻辑错误。

  • 先确认:通过 dmesg 或 journalctl 查找 OOM Killer 记录,确认是否因内存超限被杀。
  • 先处理:调整 systemd 服务的 MemoryLimit 限制或增加物理内存/swap 空间。
  • 再验证:观察服务状态及系统日志是否仍有 kill 记录,确保内存压力解除。

命令速用版

以下命令用于快速定位退出原因和内存状态,适用于大多数 Linux 发行版。

# 查看服务状态及退出码
systemctl status <服务名>

# 查看内核日志中的 OOM 杀死记录
dmesg -T | grep -i "killed"

# 查看 systemd 日志详情
journalctl -u <服务名> -n 50

# 查看当前内存使用情况
free -h

为什么会这样

退出码 137 是 Linux 进程被 SIGKILL 信号终止的标准返回值,计算方式为 128 + 9(信号编号)。

在 Systemd 管理的服务中,该状态码通常不是应用主动退出,而是操作系统内核触发了 OOM Killer(Out of Memory Killer)。当系统物理内存和交换空间即将耗尽时,内核为了防止系统完全僵死,会根据评分机制选择占用内存较高的进程强制杀死。Systemd 服务进程因短时间内申请大量内存,容易成为 OOM Killer 的目标,导致服务意外中断并返回 137 状态码。

Systemd 服务退出码 137 是什么意思如何优化内存限制

分步处理

按照以下顺序排查和优化,避免盲目调整配置。

1. 确认 OOM 事件
登录服务器执行dmesg -T | grep -i "killed"或journalctl -k `--since`="1 hour ago" | grep -i "oom"。如果日志中出现"Out of memory: Killed process"且进程名匹配你的服务,确认为内存不足导致。

2. 检查 Systemd 内存限制
查看服务配置文件(通常位于/etc/systemd/system/或/lib/systemd/system/),检查是否设置了MemoryLimit或MemoryMax。如果限制值过小,适当调大或注释掉该行以使用系统默认限制。

3. 优化系统内存资源
若物理内存不足,可配置 swap 分区作为缓冲。使用free -h查看 available 内存,若所剩无几,需增加 swap 空间。注意 swap 仅作为临时缓解方案,不能替代物理内存扩容。

Systemd 服务退出码 137 是什么意思如何优化内存限制

4. 调整应用并发或负载
如果服务支持并发控制(如编译任务、线程池),降低并行任务数可减少瞬时内存峰值。例如将并行任务数减半,虽可能增加耗时,但能避开 OOM 风险。

怎么验证是否生效

执行优化后,重启服务并持续观察一段时间。

1. 状态检查
运行systemctl status <服务名>,确认 Active 状态为"active (running)"且退出码不再出现 137。

2. 日志监控
持续监控dmesg和journalctl日志,确保没有新的 OOM kill 记录生成。

Systemd 服务退出码 137 是什么意思如何优化内存限制

3. 内存水位
使用free -h或监控工具观察内存使用率,确保在业务高峰期系统 available 内存未耗尽。

常见坑

  • Swap 不是性能提升方案:增加 swap 分区只能防止进程被杀,无法解决物理内存不足导致的性能下降,过度依赖 swap 会导致系统响应变慢。
  • 137 不是应用错误:不要试图在代码中捕获或修复 exit 137,这是内核行为,应用层无法拦截 SIGKILL 信号。
  • 资源限制冲突:同时存在 systemd 限制、cgroup 限制和 ulimit 限制时,取最严格的那个生效,需全面检查。

常见问题

退出码 137 和 143 有什么区别?

137 代表 SIGKILL(信号 9),通常是内核 OOM 强制杀死;143 代表 SIGTERM(信号 15),通常是系统或用户发起的正常终止请求。

程序代码里能捕获 exit 137 吗?

不能。SIGKILL 信号无法被捕获、阻塞或忽略,进程会被内核直接终止,因此代码中无法处理该退出码。

增加 swap 后为什么还是报 137?

可能物理内存和 swap 总和仍不足以支撑峰值负载,或者磁盘 IO 瓶颈导致 swap 交换过慢触发超时,需考虑增加物理内存或优化程序内存占用。

参考来源

  • Android13 编译内存不足?手把手教你解决 ninja exit status 137 错误 (附 swap 分区优化)
  • 为什么容器退出码显示 137?这通常意味着进程被系统强制杀死了吗?
  • docker 常见问题排查处理
  • Kubernetes 故障系列-OOMKilled 排障实战 Exit Code 137