服务器频繁OOM报错swap分区扩容根治完整脚本

服务器频繁出现 OOM(Out Of Memory)报错,通常意味着物理内存不够用,而 swap 又没有及时兜底。
根本解法是给系统扩容 swap,让进程在内存吃紧时能先落到交换分区,而不是被内核直接杀掉。
本文提供一套完整的 swap 扩容脚本,并附带检查和验证命令,你复制到终端就能用,不需要懂太深的内核原理。

扩容前先看现状:确认问题在内存还是 swap

执行以下命令,先看当前内存和 swap 占用:

free -h
swapon --show

如果 free -h 中 swap 那一行为空,或者 swapon --show 没有任何输出,说明系统当前没有启用 swap。
如果 swap 已有但很小,比如 512M,且 free -h 显示 used 接近 total,那么频繁 OOM 基本就是 swap 不足导致。

另外还可以看系统日志确认:

grep -i 'out of memory' /var/log/messages 或 /var/log/syslog

确认是内存紧张后,就可以执行下面的扩容步骤。

一键扩容:swap 文件自动创建并启用脚本

这里不修改原始磁盘分区,而是用 swap 文件方式扩容,优点是安全、不用停机、适合云服务器和宝塔环境。
将以下内容保存为 swap_expand.sh

#!/bin/bash
# swap 自动扩容脚本,默认增加 4G,可传参数自定义大小,如 ./swap_expand.sh 8G
SWAP_SIZE="${1:-4G}"
SWAPFILE="/swapfile_extra"

# 如果文件已存在,先禁用并删除,避免重复创建
if [ -f "$SWAPFILE" ]; then
    swapoff "$SWAPFILE" 2>/dev/null || true
    rm -f "$SWAPFILE"
fi

# 创建指定大小文件(优先 fallocate,失败时回退 dd)
if ! fallocate -l "$SWAP_SIZE" "$SWAPFILE"; then
    dd if=/dev/zero of="$SWAPFILE" bs=1M count=$(echo "$SWAP_SIZE" | tr -d 'G') * 1024) 2>/dev/null
fi

chmod 600 "$SWAPFILE"
mkswap "$SWAPFILE"
swapon "$SWAPFILE"

# 写入 /etc/fstab 实现开机自动挂载
grep -q "$SWAPFILE" /etc/fstab || echo "$SWAPFILE none swap sw 0 0" >> /etc/fstab

# 将 swappiness 调整为 10,让系统优先使用物理内存,减少不必要的换页
sysctl vm.swappiness=10
grep -q 'vm.swappiness' /etc/sysctl.d/99-swap.conf 2>/dev/null || echo 'vm.swappiness=10' >> /etc/sysctl.d/99-swap.conf

# 输出最终结果
echo "扩容完成:"
swapon --show
free -h

给脚本执行权限并运行:

chmod +x swap_expand.sh
./swap_expand.sh 4G   # 这里的 4G 可按需修改,比如 8G

如果 dd 回退分支里的括号计算写错了,可以简化为手动执行 dd,或者直接固定用 fallocate。
对于大多数 ext4 文件系统,fallocate 都支持,不需要走 dd。

执行脚本后重点检查这几项

运行完脚本,不要直接关终端,依次确认:

  • swapon --show 能看到 /swapfile_extra,且大小正确。
  • free -h 中 swap 总量变大了,可用值不再为 0。
  • cat /etc/fstab 最后一行有 /swapfile_extra none swap sw 0 0
  • 重启服务器后再次执行 swapon --show,确保开机自动挂载生效。

如果重启后 swap 没生效,检查 /etc/fstab 格式和文件权限是否 600。

避坑指南:不要盲目加大 swap

swap 不是越大越好,以下几个坑要避开:

不要忽略物理内存。 swap 只适合缓解突发内存压力,如果业务本身就需要大量内存,优先买内存或优化程序,不能长期靠 swap 硬撑,否则磁盘 I/O 会拖慢整体性能。

不要使用稀疏文件。truncate 创建的 swap 文件是稀疏的,mkswap 会报错。
脚本里必须用 fallocatedd 真实占满磁盘。

不要在 SSD 上频繁用 dd 创建超大文件。 虽然脚本支持 dd 回退,但大容量时可能耗时较长,建议先确认磁盘空余空间够用。

不要乱改 swappiness。 这里设置为 10 是保守值,适合大多数 Web 服务器。
如果你希望更早使用 swap,可以调到 60,但不建议超过 100。

注意云服务器厂商的虚拟化限制。 部分云平台不允许在内核层直接调整某些 swap 参数,但本文的 swap 文件方式基本通用,遇到权限问题先检查是否使用了 sudo。

如何确认 OOM 问题已经被根治

先跑一轮压力测试,或者直接重新运行之前的负载任务:

stress-ng --vm 2 --vm-bytes 2G --timeout 60s

如果系统没有报 OOM,并且 free -h 能看到 swap 被消耗了一部分,说明交换分区已经开始兜底。
再查看系统日志:

dmesg | tail -20

没有出现 Out of memory 关键字,就说明扩容有效。

如果你用的是宝塔面板,也可以直接在面板的「终端」里执行同样的命令,不需要登录 SSH。
手动改完脚本后,建议先在测试环境跑一次,确认无误再应用到生产服务器。

如果你的服务器还在频繁 OOM,多半是内存本身已经不够用,扩容 swap 只能缓解,后续仍要结合监控工具(如 sartop)定位具体是哪个进程吃内存。
解决问题后,还要记得定期检查 /swapfile_extra 的磁盘占用,避免日志增长把磁盘塞满。

分享到:
上一篇
长尾关键词矩阵搭建提升谷歌自然搜索流量实操
下一篇
宝塔部署定时任务磁盘满自动清理日志脚本
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意