内存泄漏定位排查解决站点频繁OOM

网站或应用服务器频繁报出"Out of Memory"错误,进程自动挂掉,重启后又复发——这是典型的内存泄漏信号。
本文从最基础的监控命令开始,带你一步步定位泄漏源并彻底解决,就算你是刚接触服务器的新手也能跟着操作。

先确认系统内存到底怎么用光了

在动手之前,先看清楚内存的真实分配情况。
很多新手看到free -m显示used很高就慌了,其实Linux会把空闲内存用于缓存(buff/cache),应用不一定缺内存。
正确做法是:

  1. 检查整体内存:执行 free -h 查看总量、已用、可用和交换分区。重点关注available列,它才是真正可分配给新进程的内存。如果available持续低于总内存的10%,说明有压力。
  2. 查看进程内存排名ps aux --sort=-%mem | head -10 显示内存占用最高的前10个进程。记下PID和%MEM。
  3. 确认OOM killer是否干预dmesg | grep -i "oom"journalctl -k | grep -i "oom"。如果看到"Out of memory: Kill process"的记录,说明系统确实因内存不足杀掉了进程。

根据进程类型深入定位泄漏源

不同的进程需要不同的排查工具,这里按常见场景给出对应方法。

Java 应用(Tomcat、Spring Boot等)

  • 先用 jstack -l 看线程堆栈,但内存泄漏主要看堆
  • 使用 jmap -heap 得到堆配置和当前使用情况。如果老年代(Old Generation)持续增长不下降,大概率泄漏。
  • 导出堆转储快照:jmap -dump:live,format=b,file=/tmp/heap.hprof 。然后用 Eclipse Memory Analyzer (MAT) 或 VisualVM 本地分析。

PHP-FPM 或 Node.js

  • PHP:修改 php.ini 开启 memory_limit 日志:log_errors = On,再配合 error_reporting(E_ALL),查看 php-fpm 慢日志(pm.status_path)。也可以用 strace -p -e trace=brk 观察内存分配。
  • Node.js:开启 inspect 模式:node --inspect app.js,然后在 Chrome 开发者工具的 Memory 标签中抓取堆快照,对比多次快照中未释放的对象。

其他二进制程序(Nginx、MySQL等)

  • 使用 slabtop 查看内核 slab 缓存是否异常(常见于 Nginx 或 MySQL 的连接池泄漏)。
  • 运行 valgrind --leak-check=full ./your_program,不过生产环境建议在调试机或低峰期执行。

避坑指南:这些地方最容易翻车

  • 不要手动 kill 掉高内存进程:如果进程在稳定提供服务,kill 后业务中断,而且没有解决泄漏根因。先分析再决定。
  • 堆转储文件很大时注意磁盘空间jmap 导出的文件可能比实际堆大,提前 df -h 检查根分区或 /tmp 容量。
  • 别盲目增加 swap:swap 能缓解瞬时压力,但无法阻止泄漏继续吃内存,反而让系统变慢几十倍。
  • 小心 cgroup 或容器场景:在 Docker 或 Kubernetes 里,free -h 显示的是宿主机的内存,要用 cat /sys/fs/cgroup/memory/memory.usage_in_bytes 查看容器真实使用。

修复后如何验证泄漏已被解决

完成代码修复或配置调整后,不要马上觉得没事了。
按以下步骤验证:

  1. 重启进程(或整个容器/服务),确保从干净状态开始。
  2. 持续监控内存:用 watch -n 5 'ps aux --sort=-%mem | head -10' 每5秒刷新一次,观察目标进程内存是否缓慢爬升。
  3. 设置阈值报警:比如使用 nmon 或者集成 prometheus + node_exporter,当进程内存占用连续增长超过 80% 时告警。
  4. 模拟高负载(可选):用 abwrk 压测几分钟,看内存是否仍在可控范围。

如果观察24小时内存曲线平稳,没有触发OOM killer记录,基本可以确认问题已解决。

高频问题解答

Q:重启后内存占用又恢复到很高,怎么办?
A:说明泄漏源还在,检查是否有定时任务或常驻脚本启动时加载了大量数据。可以结合 systemd 日志或 /var/log/messages 找到启动后第一个高内存进程。

Q:有没有一键排查工具?
A:htop 可以交互查看进程树和内存排序,smem 能按实际物理内存排序。对于 Java 环境,可以搜 “阿里巴巴 Arthas” 用 dashboard 命令实时监控堆内存变化。

Q:虚拟内存(VSS)很高但实际内存(RSS)不高,需要管吗?
A:RSS 才是真实占用的物理内存,VSS 高通常是因为 fork 或共享库,不直接导致 OOM,可暂时忽略。

如果你正在面对服务器频繁 OOM,建议先按本文的监控定位命令排查,再针对具体进程选择分析工具。
遇到拿不准的异常时,多回看避坑部分,避免误操作扩大故障。

分享到:
上一篇
一键清理内存缓存释放服务器资源:Linux服务器一键清理内存
下一篇
定时清理网站缓存文件提升访问速度
1
系统公告

机房迁移升级通知

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