使用自定义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 杀进程 → 释放内存 → 系统恢复
相关推荐
cjp5603 小时前
011. UG二次开发,UG管道通讯服务器与wpf客户端通讯
linux·运维·服务器
上官唐云3 小时前
2024届本科 | C++ Linux服务端开发求职:从嵌入式到底层服务端的技术之路(附开源项目+简历)
linux·c++·开源·求职招聘
Zucker n3 小时前
Ubuntu24.04结合ollama本地使用Hermes
linux·ubuntu
邪修king3 小时前
Linux系统篇(二十三) 基础 IO:从“文件”到“文件描述符”,彻底理解重定向
android·java·linux
正仪4 小时前
systemd 是什么?
linux·运维·windows
暖核4 小时前
华为云运维三件套实战:云审计 + 云监控 + 云日志完整操作指南
linux·运维·华为云
AI+程序员在路上4 小时前
Rv1126b与手机(SPP蓝牙串口APP)蓝牙通信流程
linux·c语言·智能手机
虚无的纽扣4 小时前
【Linux】进程第二课:进程优先级和环境变量
linux·运维·服务器
maosheng11465 小时前
【无标题】linux中企业容易考的的小知识点1(rhcsa)
linux·运维·服务器