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

以下是完整的安装与配置方案。该方案通过极简的 Bash 脚本监控内存,在可用内存低于 512 MiB 时强制触发内核 OOM Killer,从而避免系统陷入漫长的内存回收死等,保持桌面响应。

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. 优化内核内存水位线(推荐)

提高内核保留的紧急空闲内存,促使后台回收线程提前工作,减少前台 GUI 进程卡顿。

bash 复制代码
echo "vm.min_free_kbytes=524288" | sudo tee /etc/sysctl.d/99-min-free.conf
sudo sysctl --system

3. 部署监控脚本

创建一个纯 Bash 内建命令编写的脚本,每 0.1 秒检查一次可用内存。

bash 复制代码
# 创建并写入脚本内容
sudo tee /usr/local/bin/oom-sysrq.sh > /dev/null << 'EOF'
#!/bin/bash
# 阈值:512 MiB (524288 kB)
THRESH=524288
# 触发后的冷却时间(秒)
COOLDOWN=5

while :; do
    # 纯 Bash 内建读取,避免 fork 外部命令
    while read -r key val _; do
        case $key in
            MemAvailable:) avail=$val ;;
        esac
    done < /proc/meminfo

    if (( avail < THRESH )); then
        # 强制触发内核 OOM Killer
        echo f > /proc/sysrq-trigger
        sleep "$COOLDOWN"
    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

5. 验证配置

检查服务状态,确保其正在运行:

bash 复制代码
systemctl status oom-sysrq.service

应显示绿色的 active (running)

6. 查看触发记录

当脚本介入时,可以通过以下命令查看日志:

bash 复制代码
# 查看内核的 OOM 记录(包含 "SysRq: Manual OOM execution" 字样即为脚本触发)
sudo dmesg -T | grep -i -E "sysrq|out of memory" | tail -10

7. 卸载与回退

如果未来不再需要此方案,可通过以下命令彻底清理:

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 rm -f /etc/sysctl.d/99-min-free.conf
sudo sysctl --system

# 清理 systemd 状态
sudo systemctl daemon-reload
sudo systemctl reset-failed
相关推荐
Brilliantwxx1 小时前
【STM32】 初认识USART串口
linux·stm32·单片机·嵌入式硬件·架构
ONLYOFFICE2 小时前
ONLYOFFICE成为Linux操作系统 – Winux的预装办公套件
linux·运维·服务器
mounter6252 小时前
从内核安全到可编程基础设施:Meta 的 eBPF 实践与形式化验证探索
linux·ebpf·linux kernel·kernel
新时代牛马2 小时前
嵌入式 Linux WiFi 框架完整篇:从cfg80211、mac80211 到wpa_supplicant
linux·运维·服务器
吴声子夜歌2 小时前
Linux命令——打印
linux·运维·服务器
企鹅的蚂蚁2 小时前
Linux 开发板串口调试:picocom 从识别到退出的完整用法
linux·运维·服务器
bksczm2 小时前
从 “什么是 MySQL“ 到库与表的完整操作(MySQL基础篇)
linux·数据库·mysql
企鹅的蚂蚁2 小时前
LubanCat RK3588 实时内核移植第一步:先确认硬件与系统版本
linux·lubancat·嵌入式linux·freempt_rt
是个西兰花3 小时前
网络基础1
linux·网络·c++·智能路由器