Linux OOM 不是内存小,90% 的人都理解错了

为什么你的服务器总是 OOM?别急着买内存条

很多站长和运维同学一看到服务器出现 OOM(Out of Memory)就认为内存不够用,赶紧升级配置。
其实,90% 的 OOM 不是物理内存太小,而是内核的内存分配策略或进程资源限制出了问题
今天我们就从零开始,一步步搞清楚 OOM 的真相,并找出对应的解决方法。

认识 OOM 的两大元凶

OOM 的全称是 Out of Memory,但 Linux 内核并不是等到物理内存真正用光才触发。
在以下两种情况下,OOM Killer(内存溢出杀手)会强制杀掉进程:

  • 过度分配(Overcommit):Linux 默认允许进程申请比实际物理内存 + 交换空间更多的内存(这叫 overcommit)。大部分进程不会把申请的内存全用掉,但一旦所有进程同时大量写入,内存瞬间撑爆,内核只好启动 OOM Killer。
  • cgroup 内存限制:在使用容器(如 Docker)或 systemd 服务时,如果设置了 MemoryLimit,即使物理内存还有剩余,进程也会被 OOM Kill。

所以,OOM 不等于物理内存小,理解这一点才能对症下药。

第一步:确认当前是否被 OOM 误杀

在动手调整前,先确认最近有没有 OOM 事件以及原因。

# 查看系统日志中的 OOM 记录
dmesg | grep -i oom
# 或者查看内核日志文件
sudo grep -i oom /var/log/kern.log

输出类似:

[123456.789] oom-kill:constraint=CONSTRAINT_NONE...
[123456.789] Memory cgroup out of memory: Killed process 12345 (nginx)

第二行如果提到 Memory cgroup,说明是 cgroup 限制导致的,与物理内存大小无关。

第二步:检查内存分配策略和 swap 配置

查看当前 overcommit 设置

sysctl vm.overcommit_memory
  • 0 – 默认,内核根据当前空闲内存估算是否允许 overcommit(启发式)。
  • 1 – 总是允许 overcommit(可能更容易触发 OOM)。
  • 2 – 禁止超过某个比例(vm.overcommit_ratio 控制)的 overcommit,最保守。

大多数 OOM 问题的原因是 默认(0) 过于乐观
可以临时改成 2 试试效果:

sudo sysctl -w vm.overcommit_memory=2
sudo sysctl -w vm.overcommit_ratio=50   # 最多允许物理内存+swap的50%

检查 swap 是否太小

如果没有 swap 或 swap 很小,内存紧张时内核无法回收内存,OOM 更容易发生。

free -h | grep -i swap

如果 Swap 总行为 0,建议添加 swap 文件(参考下方避坑部分)。

第三步:调整配置,从根源减少 OOM

方案 A:修改 sysctl 参数持久化

用编辑器打开 /etc/sysctl.conf,添加或修改以下内容:

vm.overcommit_memory = 2
vm.overcommit_ratio = 50
vm.swappiness = 10

然后执行 sudo sysctl -p 生效。swappiness 控制内核使用交换空间的倾向,值越低越优先使用物理内存,可以减少 OOM Killer 的触发。

方案 B:为特定进程设置 OOM 保护

如果某个服务(如 MySQL)经常被杀,可以给它设置更高的 oom_score_adj,让内核优先杀其他进程:

# 找到进程 PID
ps aux | grep mysqld
# 设置 oom_score_adj(取值范围 -1000 到 1000,越小越不容易被杀)
sudo echo -500 > /proc/[PID]/oom_score_adj

方案 C:检查并调整 cgroup 限制

如果是容器或 systemd 服务:

# 查看 systemd 服务的 MemoryLimit
systemctl show nginx.service | grep MemoryLimit

# 临时调整(单位字节)
sudo systemctl set-property nginx.service MemoryLimit=512M

避坑指南:这几点90%的人想错了

  1. 不要一上来就加内存。先查看 dmesg 日志,如果出现 constraint=CONSTRAINT_MEMCG,加了物理内存也解决不了,因为 cgroup 限制没解除。
  2. swap 一定要有,哪怕只有1GB。没有 swap 的服务器 OOM 概率会高很多。添加 swap 文件:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久挂载:在 /etc/fstab 中添加一行
  1. 别盲目调高 vm.overcommit_ratio 到 100,那等于关闭保护,会让系统更不稳定。

效果验证:如何确认问题已解决

调整后,进行压力测试来模拟高内存场景:

# 使用 stress 工具(先安装:sudo apt install stress 或 yum install stress)
stress --vm 4 --vm-bytes 512M --timeout 30s

观察是否还会触发 OOM:

dmesg | tail -5    # 如果没有新的 oom-kill 信息,说明配置有效
free -h             # 确认内存使用率变化

也可以观察 /var/log/syslog/var/log/messages
如果连续一周没有 OOM 事件,说明调整正确。

总结

遇到 OOM 别第一时间买内存条。
按照本文步骤检查 overcommit、swap 和 cgroup 配置,通常能解决大部分问题。
记住,Linux OOM 不是内存小,90% 的人都理解错了这句话背后的核心是内存管理策略。
如果你按照上述方法操作后仍有疑问,建议在调整前先完整备份关键配置,并在测试环境验证再上线。

分享到:
上一篇
宝塔面板被黑?别慌,按这个步骤找回数据
下一篇
最危险的 Nginx 漏洞,一键修复教程
1
系统公告

泽御云五一特惠活动🔥

泽御云持证合规运营,资质齐全可查,长久稳定! 五一限时多重福利同步开启: ✅ 香港 2 核 2G 云服务器超值拼团,低价入手团长免费 ✅ 4 核 4G 多机房年付拼团,性价比拉满 ✅ 内蒙古新区限时 7 折(zeyuyunnmg)特惠,专属优惠码锁价续费 ✅ 全站通用 75 折优惠,老用户充值享专属赠金 官方站点:zeyuyun.com 合规资质齐全|售后有保障|活动限时错过不再有
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意