服务器内存泄漏排查:从发现到定位

服务器内存泄漏排查:从发现到定位

你的服务器内存使用率一直在涨。周一30%,周二40%,周五80%。你重启了一下,回到30%。下周又重复一遍。

你知道有内存泄漏,但不知道哪个进程在泄漏。今天讲一套排查方法,帮你找到元凶。

先看一个数据

内存泄漏是服务器常见问题之一。在排查过程中,通过观察内存使用趋势、检查/proc/meminfo和进程内存映射,可以逐步定位泄漏源。开发环境中的内存泄漏通常比生产环境更容易定位,因为你有更多工具可用。

第一步:确认是内存泄漏,不是正常增长

先区分“内存泄漏”和“正常缓存增长”。

free -h查看内存分布

text

              total   used   free   shared  buff/cache   available
Mem:           7.6G   2.1G   1.2G    150M       4.3G        5.0G
  • used:进程实际占用的内存
  • buff/cache:系统缓存(可以回收,不是泄漏)
  • available:真正可用的内存

如果used持续增长,而buff/cache变化不大,可能是内存泄漏。如果只是buff/cache增长,是正常的缓存行为,系统会在内存紧张时自动回收。

查看内存趋势

bash

# 查看过去几天的内存变化
sar -r

如果安装了sysstat,sar -r会显示每天的内存使用记录。观察趋势,持续上升通常需要关注。

第二步:用top定位高内存进程

bash

top -o %MEM

-o %MEM按内存使用率排序,最耗内存的进程在最上面。

关注

  • %MEM超过10%的进程
  • RES(常驻内存)持续增长的进程
  • VIRT(虚拟内存)异常高的进程

记录PID,进入下一步。

第三步:追踪进程的内存变化

ps查看单个进程的内存变化:

bash

# 查看某个进程的VSZ(虚拟内存)和RSS(常驻内存)
ps -p PID -o vsz,rss,comm

多次运行,观察RSS是否持续增长。RSS持续上升而业务量没有增加,基本可以确认该进程有内存泄漏。

pmap查看进程的内存映射

bash

pmap -x PID

输出会显示进程占用的所有内存区域,以及各区域的权限和大小。如果看到大量[anon]匿名内存块,可能是程序申请了内存但未释放。

第四步:查看/proc/meminfo分析系统内存

bash

cat /proc/meminfo

关键字段解读:

字段含义
MemTotal总内存
MemFree空闲内存
MemAvailable真正可用内存
Buffers块设备缓存
Cached文件系统缓存
Slab内核数据结构缓存
SReclaimable可回收的内核内存
SUnreclaim不可回收的内核内存(持续增长可能是内核泄漏)

如果SUnreclaim持续增长,可能是内核内存泄漏。

第五步:检查Java/Python应用的堆内存

Java应用

bash

# 查看Java堆内存使用
jstat -gc PID

关注OGC(老年代GC次数)和OU(老年代使用量)。如果OU持续增长而OGC没有相应增加,说明老年代存在内存泄漏。

bash

# 查看堆内存配置
jcmd PID VM.flags | grep -E "Xms|Xmx"

Python应用

Python的内存管理相对简单,但某些情况下(如循环引用或第三方C扩展未正确管理内存)仍会导致泄漏。用tracemalloc模块或在开发环境使用memory-profiler可以帮助定位。

第六步:检查是否因为文件句柄未关闭

有时内存泄漏是资源泄漏的副产物。程序打开了文件但没关闭,可能间接导致内存持续增长。

bash

# 查看进程打开的文件数
lsof -p PID | wc -l

持续增长说明资源泄漏。

排查顺序总结

  1. 确认是泄漏不是缓存free -hused,不是buff/cache
  2. 找高内存进程top -o %MEM
  3. 追踪单个进程ps -p PID -o vsz,rss多次观察
  4. 看内核内存cat /proc/meminfoSUnreclaim
  5. 看堆内存:Java用jstat,Python用tracemalloc
  6. 查资源泄漏lsof -p PID | wc -l

真实案例

一台Java应用服务器内存持续增长,每周重启一次。top发现一个Java进程占用6GB内存,jstat显示老年代使用量不断上升,但GC回收量很小。分析堆转储后发现是某个缓存类没有设置过期时间,缓存对象持续积累。调整缓存配置后,内存稳定在4GB。

最后一句

内存泄漏排查的关键是区分:是正常缓存增长,还是进程内存泄漏,还是内核内存问题。

先用free -h排除缓存干扰,再用top找到嫌疑进程,然后用ps追踪进程的持续增长趋势。如果进程内存稳定但系统内存持续增长,检查/proc/meminfoSUnreclaim。泄漏一定有痕迹,只是看你有没有找到对的工具。

知识库

服务器CPU使用率忽高忽低?排查思路与解决方法

2026-7-2 18:20:48

知识库

网站HTTPS配置后常见问题:混合内容、证书链不完整

2026-7-3 18:29:48

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧