服务器内存飙升、OOM 自动重启?完整排查方案
OOM = Out Of Memory(内存溢出)。当 Linux 系统物理内存 + Swap 都耗尽时,内核会启动OOM Killer 机制,强制杀掉占用内存最高的进程,保护系统不彻底卡死。被杀的通常是:Java、PHP-FPM、Nginx、MySQL、Python 等应用严重时系统直接崩溃、自动重启只要出现 OOM,说明内存资源已经彻底不够用或严重泄漏。
服务器经常内存莫名其妙占满、负载飙升、应用被系统杀死、甚至整机自动重启,这是线上最典型、也最让人头疼的故障之一。 很多人遇到只会重启服务器,治标不治本,过几天又复发。
我最近在河南一家知名IDC公司郑州易方科贸(861.cn)碰到过种问题,我将给出完整、可落地、从定位到根治的排查方案,新手也能一步步照着做。
一、先搞懂:什么是 OOM?为什么会自动重启?
OOM = Out Of Memory(内存溢出)。
当 Linux 系统物理内存 + Swap 都耗尽时,内核会启动 OOM Killer 机制,强制杀掉占用内存最高的进程,保护系统不彻底卡死。
- 被杀的通常是:Java、PHP-FPM、Nginx、MySQL、Python 等应用
- 严重时系统直接崩溃、自动重启
只要出现 OOM,说明内存资源已经彻底不够用或严重泄漏。
二、第一步:快速确认是不是 OOM 导致重启
先判断故障根因,不要盲目优化。
1. 查看系统 OOM 日志
bash
运行
dmesg | grep -i "out of memory"
dmesg | grep -i oom
如果出现类似内容:
plaintext
Out of memory: Kill process 1234 (java)
说明就是 OOM 杀死了进程。
2. 查看系统日志(更完整)
bash
运行
grep -i "oom" /var/log/messages
grep -i "oom" /var/log/syslog
能看到:
- 什么时候触发 OOM
- 哪个进程被杀死
- 当时内存占用情况
3. 看当前内存状态
bash
运行
free -h
重点看:
used接近总内存swap被占满 基本就是内存溢出环境。
三、第二步:定位谁在吃内存?
1. 实时看内存占用最高的进程
bash
运行
top
按 M 键(大写),按内存排序。
重点关注:
- Java 进程
- MySQL
- PHP-FPM 子进程过多
- Nginx
- Python/NodeJS 应用
- 定时任务、爬虫、导入导出脚本
2. 更直观的内存排行
bash
运行
ps aux --sort=-%mem | head -10
直接列出内存占用前 10 进程,一眼找到元凶。
四、第三步:内存飙升的 5 大真实原因
1. 内存泄漏(最常见)
应用没有正确释放内存,越跑占得越多。 典型:
- Java 内存泄漏
- Go/Python 长驻进程缓存失控
- 连接池不释放
- 本地缓存无过期策略
表现:
- 内存缓慢上涨,几天必爆
- 重启后恢复,之后继续涨
2. 进程数量爆炸
PHP-FPM、Nginx、uWSGI 等子进程疯狂被拉起,导致总内存爆掉。
bash
运行
ps aux | grep php-fpm | wc -l
ps aux | grep nginx | wc -l
几百上千个进程,内存直接被吃光。
3. 一次性大任务压垮内存
一次性加载大量数据到内存:
- 大数据导入导出
- 大文件读取
- 全表查询不加 limit
- 报表统计、批量计算
瞬间把内存打满,直接 OOM。
4. 日志 / 缓存占满 Buff/Cache
Linux 会把空闲内存用作文件缓存,看起来内存很高,但正常情况下不会触发 OOM。 如果 Buff/Cache 异常巨大,可能是:
- 大量小文件读写
- 日志疯狂输出
- 磁盘 IO 异常
可以手动释放:
bash
运行
sync && echo 3 > /proc/sys/vm/drop_caches
但这只是临时缓解。
5. Swap 配置不当或没有 Swap
没有 Swap → 内存一满直接 OOM Swap 太小 → 高并发下依然顶不住
五、第四步:从临时应急到彻底解决
(1)应急处理(快速恢复)
- 杀死异常占用内存的进程
bash
运行
kill -9 进程PID
- 重启异常服务
- 增加 Swap(临时救命)
bash
运行
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
- 限制突发大流量、暂停批量任务
注意:应急只是恢复业务,不是根治。
(2)根治方案:从应用到系统
1. 应用层限制内存(最有效)
- Java:设置 Xmx 最大堆内存
plaintext
-Xmx2G -Xms2G
- PHP-FPM:限制最大子进程数、请求回收次数
- NodeJS/Python:控制并发、限制内存缓存
2. 修复内存泄漏
- 检查代码:连接未关闭、缓存未清理、死循环
- 检查第三方库、中间件版本 bug
- 开启应用内存监控
3. 控制进程数量
以 PHP-FPM 为例:
plaintext
pm.max_children = 50
pm.process_idle_timeout = 10s
避免进程无限创建。
4. 优化大查询、大任务
- SQL 加 limit,避免全表加载
- 大文件分块读取
- 耗时任务异步化、队列化
- 大数据导出走临时文件,不加载内存
5. 系统层优化
- 配置合理 Swap(一般等于内存或 1/2)
- 设置内存水位线告警
- 开启日志轮转,避免日志疯长
- 必要时升级服务器内存配置
六、第五步:预防监控,避免再次发生
- 配置内存使用率告警(超过 85% 告警)
- 监控 Swap 使用情况
- 监控进程数量、应用堆内存
- 定时清理日志、缓存
- 关键服务设置自动重启、自我保护
- 高并发业务做集群、负载均衡
七、一句话排查流程
- 看 OOM 日志 → 确认是内存溢出
- top/ps 找占用内存最高的进程
- 判断是泄漏、进程过多、还是大任务导致
- 临时杀进程 / 加 Swap 恢复业务
- 从应用配置、代码、系统层面彻底优化
- 加监控,防止复发
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)