Linux内存泄漏排查需先通过top/htop或watch命令监控RSS持续增长,再分析/proc/PID/smaps中Rss与Anonymous字段变化,结合perf或jemalloc等工具定位分配源头,并排除page cache、GC延迟等伪泄漏场景。

Linux内存泄漏排查的关键在于快速识别哪个进程的内存持续增长,并确认是否真为泄漏而非正常缓存行为。重点看 RSS(常驻内存集)变化趋势,结合进程生命周期与内存分配模式综合判断。
观察进程内存增长:top / htop + 持续监控
运行 top 后按 M 按内存使用排序,重点关注 RES(即 RSS)列;htop 更直观,支持鼠标滚动和颜色高亮。若发现某进程 RSS 随时间推移稳定上升(如每小时增 10–50 MB),且不随负载下降而回落,需进一步分析。
- 用 watch -n 5 'ps -eo pid,ppid,rss,comm --sort=-rss | head -10' 每 5 秒刷新一次前 10 大 RSS 进程
- 对可疑进程记录 PID,持续 10–30 分钟观察 RSS 是否线性增长(排除短暂缓存占用)
- 注意区分 VIRT(虚拟内存)和 RSS(物理内存)——泄漏通常反映在 RSS 上
确认是否为真实泄漏:/proc/PID/smaps 分析
进入 /proc/[PID]/smaps 查看详细内存分布。重点关注以下字段:
- Rss: 当前实际占用物理内存(核心指标)
- MMUPageSize: 若大量页为 4 kB 但无对应释放,可能小块 malloc 泄漏
- Anonymous: 非文件映射内存(如 malloc/new 分配),持续增长是泄漏强信号
- Heap / Stack / VmallocChunk: heap 区持续扩大(尤其 glibc 的 brk/mmap 行为)需警惕
可对比两次采样中 Anonymous 和 Rss 差值,若增长量远超业务数据量(如处理 1KB 请求却增 1MB 内存),大概率存在泄漏。
定位代码源头:动态追踪与堆栈捕获
对运行中的进程启用内存分配追踪:
- 用 gdb -p [PID] 附加后执行 call malloc_stats()(仅限 glibc,输出当前堆状态)
- 预加载 libmemstat 或使用 valgrind --tool=memcheck(需重启进程,适合测试环境)
- 生产环境推荐 perf record -e 'mem-alloc:*' -p [PID](内核 5.15+ 支持),配合 perf script 查看高频分配点
- 若进程用 jemalloc,设置 MALLOC_CONF=prof:true,prof_prefix:jeprof.out 并触发 mallctl prof.dump true
辅助判断:排除常见伪泄漏场景
并非所有内存增长都是泄漏,需先排除以下情况:
- Page cache / Buffer cache:通过 free -h 观察 cached/buffers 占比;若 RSS 增长但 cached 不降,才更可能是进程自身问题
- Golang runtime GC 延迟:Go 程序 RSS 可能滞后于 GC,用 go tool pprof http://localhost:6060/debug/pprof/heap 查看实时堆对象
- JVM Old Gen 缓慢增长:检查 GC 日志,确认是否 Full GC 后内存未回落,再结合 jmap -histo 或 jcmd [PID] VM.native_memory
- mmap 映射未 munmap:在 smaps 中搜索 mapped 字段,查看是否有大量匿名或文件映射持续存在










