防止关键进程被oom killer误杀,需调低oom_score_adj值(如-500)、降低swappiness、收紧dirty_ratio参数、禁用vm.overcommit_memory=2,并通过systemd设置oomscoreadjust和memorylimit实现双重保障。

防止关键进程被系统误杀,核心是让内核在内存紧张时“绕着走”——不把它当作 OOM Killer 的首选目标。这不是靠重启或加内存解决的临时手段,而是通过调整内核对进程的“危险评分”和回收偏好来实现的。
调低 oom_score_adj 值
Linux 用 oom_score_adj(范围 -1000 到 +1000)决定进程被杀的优先级:值越高越容易被杀,-1000 表示完全免疫。关键服务应设为负值:
- 给 nginx 主进程设为 -500:
echo -500 > /proc/$(pgrep -f "nginx: master")/oom_score_adj - Java 应用启动时直接指定:
java -XX:+UseContainerSupport -Dsun.java.command="myapp" -jar app.jar,再配合 systemd 的OOMScoreAdjust=-500 - 注意:该值只对当前进程有效,子进程继承父进程值,但需在进程启动后立即设置,否则可能已被 kill
控制内存回收倾向,减少触发 OOM 的机会
OOM 往往不是因为内存绝对不够,而是因为内核被迫进入同步回收(Direct Reclaim),卡住分配路径。可通过以下参数缓解:
- 降低 swappiness(默认 60):设为 1~10,让内核更倾向回收 Page Cache 而非换出匿名页,避免 Java 堆外内存或 mmap 区域被误判为可牺牲对象
- 收紧 dirty_ratio 和 dirty_background_ratio:例如设为 10 和 5,加快脏页回写,防止 write 系统调用被阻塞进而拖垮整体响应
- 确认 vm.overcommit_memory 不为 2:设为 1(乐观分配)更利于稳定运行,避免因 overcommit_ratio 计算偏差导致提前触发 OOM
用 systemd 做双重保障
如果进程由 systemd 管理,可在 service 文件中加入:
-
OOMScoreAdjust=-500:持久化 oom_score_adj 设置 -
MemoryLimit=4G或MemoryMax=4G:硬限制内存上限,让 cgroup 在超限时先触发内存压力通知,而非等内核全局 OOM -
Restart=on-failure+RestartSec=5:即使被杀也能快速拉起,降低业务中断感
验证与监控不能少
设完不等于万事大吉,得持续盯住两个关键点:
- 定期检查:
cat /proc/$(pidof your_process)/oom_score_adj确认值未被重置 - 监听 OOM 事件:
dmesg -T | grep "Killed process"每小时跑一次,发现就立刻溯源 - 观察 USS 趋势:用
awk '/^USS:/ {print $2}' /proc/PID/smaps抓取独占内存,持续上涨说明泄漏仍在,防护只是掩耳盗铃











