使用自定义bash脚本预防oom卡死 v2

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 杀进程 → 释放内存 → 系统恢复
相关推荐
夜听莺儿鸣8 小时前
502-003_Linux 中断与异常(一):从Linux角度理解中断与异常
linux·中断与异常·linux中断
杨云龙UP8 小时前
TDengine 3.4.2.8 Community 三节点三副本生产集群部署实战(DNode/MNode/taosAdapter/Explorer)
大数据·linux·运维·数据库·tdengine·时序库
向成科技9 小时前
XC3576H工控主板|深度适配Ubuntu 26.04 LTS,释放边缘AI与工业开发新潜能
linux·人工智能·ubuntu·机器人·硬件·主板·边缘ai
Fcy64810 小时前
Linux下 进程间关系与守护进程
linux·运维·服务器·守护进程
码农小韩10 小时前
Linux驱动理论(二)——Linux字符设备驱动
linux·嵌入式软件开发·linux操作系统·linux应用开发·linux驱动理论
well061210 小时前
Linux粘滞位与Makefile机制深度解析
linux·运维·服务器
再写一行代码就下班10 小时前
linux sh脚本在windows修改导致无法使用解决方式
java·linux·centos
额额额对了11 小时前
SPI通信
linux·c语言·汇编·单片机·嵌入式硬件·arm
子木HAPPY阳VIP11 小时前
Ubuntu 关闭防火墙操作步骤
linux·运维·ubuntu
王振超wzc11 小时前
嵌入式开发环境搭建--WM软件安装,Ubuntu操作系统安装
linux·运维·ubuntu