OOM SysRq 防卡死方案
该方案通过极简的 Bash 脚本监控内存,在物理空闲内存低于 256 MiB 时强制触发内核 OOM Killer,从而避免系统陷入内存回收死等,保持桌面响应。
原理说明
为什么用 MemFree 而不是 MemAvailable?
- MemFree:物理空闲内存,直接反映真实状态
- MemAvailable:包含可回收缓存,可能"虚高"掩盖风险
- 当 MemFree < 256MiB 时,系统确实已无退路
看门狗的作用
- 作为最后防线,防止系统陷入内存回收死等
- 当所有回收手段都耗尽时,触发 OOM Killer 杀进程释放内存
- 256MiB 是"已经没招了"的信号,触发即正确
安装步骤
1. 开启 SysRq 权限(不一定需要)
内核必须允许接收手动触发 OOM 的指令。
bash
# 临时开启(立即生效)
echo 1 | sudo tee /proc/sys/kernel/sysrq
# 永久开启(重启后依然有效)
echo "kernel.sysrq=1" | sudo tee /etc/sysctl.d/99-sysrq.conf
sudo sysctl --system
2. 部署监控脚本
创建一个 Bash 脚本,每 0.1 秒检查一次物理空闲内存。
bash
sudo tee /usr/local/bin/oom-sysrq.sh > /dev/null << 'EOF'
#!/bin/bash
# 触发阈值:256 MiB (262144 kB)
THRESH=262144
while :; do
while read -r key val _; do
case $key in
MemFree:) free=$val ;;
esac
done < /proc/meminfo
if (( free < THRESH )); then
# 强制触发内核 OOM Killer
echo f > /proc/sysrq-trigger
fi
# 0.1 秒检查一次
sleep 0.1
done
EOF
# 赋予执行权限
sudo chmod +x /usr/local/bin/oom-sysrq.sh
4. 配置 Systemd 服务
将脚本注册为系统服务,确保开机自启,并赋予其最高级别的 OOM 豁免权。
bash
sudo tee /etc/systemd/system/oom-sysrq.service > /dev/null << 'EOF'
[Unit]
Description=Trigger Kernel OOM via SysRq when memory is low
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/oom-sysrq.sh
Restart=always
RestartSec=2
# 保护脚本自身不被 OOM 杀死
OOMScoreAdjust=-1000
# 在内存压力下优先获得 CPU 调度
Nice=-10
# 限制脚本自身的最大内存占用
MemoryMax=32M
[Install]
WantedBy=multi-user.target
EOF
# 重新加载 systemd 并启动服务
sudo systemctl daemon-reload
sudo systemctl enable --now oom-sysrq.service
验证配置
检查服务状态
bash
systemctl status oom-sysrq.service
应显示绿色的 active (running)。
查看当前内存状态
bash
free -h
# 观察 MemFree 是否保持在较高水位
查看触发记录
当脚本介入时,可以通过以下命令查看日志:
bash
# 查看内核的 OOM 记录
sudo dmesg -T | grep -i -E "sysrq|out of memory" | tail -10
卸载与回退
如果未来不再需要此方案,可通过以下命令彻底清理:
bash
# 停止并禁用服务
sudo systemctl disable --now oom-sysrq.service
# 删除脚本和服务文件
sudo rm -f /usr/local/bin/oom-sysrq.sh
sudo rm -f /etc/systemd/system/oom-sysrq.service
# 恢复内核参数
sudo rm -f /etc/sysctl.d/99-sysrq.conf
sudo sysctl --system
# 清理 systemd 状态
sudo systemctl daemon-reload
sudo systemctl reset-failed
配置总结
| 项目 | 值 | 说明 |
|---|---|---|
| 判断字段 | MemFree | 物理空闲内存 |
| 阈值 | 256MB | 最后防线 |
| 检查间隔 | 0.1秒 | 每秒10次 |
| 触发方式 | SysRq | 直接触发内核 OOM |
触发链条
正常状态:
MemFree >> 256MiB → 看门狗睡觉 → 系统正常运行
极端场景:
swap 满 → kswapd 换不动 → cache 被榨干 → MemFree 开始跌
→ 跌破 256MiB → 看门狗触发 → sysrq f 杀进程 → 释放内存 → 系统恢复