商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 系统应用 > Linux怎么查看具体的进程内存泄漏情况

Linux怎么查看具体的进程内存泄漏情况

  发布于2026-08-19 阅读(0)

扫一扫,手机访问

想要确认内存泄漏,就得死死盯住RSS(VmRSS)。在业务没有增长等前提下,若观察到它持续缓慢上升,且重启后出现相同的斜率,那很可能就存在问题。可以使用watch或/proc/pid/status进行监控,同时结合pmap -x来比对[anon]/[heap]段Kbytes的增长情况。最后,还能用valgrind(需要优雅退出)或mtrace(仅适用于C语言)来验证是否有definitely lost或未配对的malloc/free操作。

Linux怎么查看具体的进程内存泄漏情况

怎么确认某个进程真在泄漏内存

别看VIRTfree里的used,盯死RSS(也就是VmRSS)——它代表进程当前真实占用的物理内存页数。泄漏的表现是:无业务增长、无缓存预热、无连接数上升的前提下,RSS持续缓慢爬升;重启后归零,几小时内又回到相同斜率。

那该怎么验证呢?可以用watch -n 30 'ps -p -o pid,comm,rss,%mem --no-headers'每隔30秒抓取一次;或者直接读取/proc//status里的VmRSS字段,即执行cat /proc//status | grep VmRSS。然后连续观察2到4小时,只有出现单调递增的趋势,才值得深入研究。

  • Ja va/Golang等带GC的语言,RSS涨不等于泄漏——得排除堆外内存(如ByteBuffer.allocateDirect)、JNI调用、或mmap文件映射未释放
  • top里按Shift+M排序后看到的RES列,和psrss是同一值,可信
  • 如果RSS稳定但VmSize(虚拟地址空间)持续增大,可能是mmapmunmap,不是传统“malloc泄漏”

pmap -x 看出哪块内存在偷偷长大

pmap -x 输出里真正要盯的是Kbytes列和Mapping列。泄漏常表现为[anon]段或[heap]段的大小随时间推移明显变大,尤其是多次执行后发现某段地址范围反复膨胀。

操作建议:
先记下初始值:pmap -x | grep -E "(^Address|anon|heap)"
过10–15分钟再跑一次,对比Kbytes变化;
若某[anon]段从1280涨到3840,且没有对应业务动作(如加载大文件、建新连接),基本就是泄漏信号。

  • 注意pmap -XX 能显示页表级细节,如果看到大量1 page4KB[anon]映射,大概率是频繁malloc小块内存却没free
  • pmap本身不报错、不告警,它只反映现状。必须人工比对多个时间点,不能单次快照下结论
  • 服务类进程(如daemon)需确保kill -15让其优雅退出,否则pmap看到的只是运行中快照,无法体现释放行为

valgrind --leak-check=full 必须等程序完整退出才出报告

valgrind不是实时监控工具,它是靠插桩拦截所有malloc/free调用,只有程序彻底退出时才汇总并报告“definitely lost”或“possibly lost”。所以对长期运行的服务,得发SIGTERM让它干净收尾,不能kill -9

关键命令:valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./your_program
输出里重点看以definitely lost开头的块,后面跟着的堆栈会精确到example.c:42这种行号。

  • 编译必须带-g,否则堆栈里只有地址,没法定位源码
  • 动态链接库路径要提前设好:export LD_LIBRARY_PATH=./lib,不然valgrind可能找不到符号
  • 性能开销极大(10–30倍慢),生产环境慎用;测试环境优先选gcc -O0 -g编译,避免优化导致行号错位

mtrace 更轻量,但只适用于已知源码的C程序

mtrace是glibc自带的轻量方案,不用额外安装,适合快速验证一段C代码是否漏free。但它要求你在源码里手动插入#include mtrace()调用,且只能捕获malloc/realloc/free路径。

步骤:
1. 在main()开头加mtrace()
2. 编译加-g
3. 运行前设export MALLOC_TRACE=/tmp/mtrace.log
4. 运行程序至结束;
5. 执行mtrace ./your_program /tmp/mtrace.log解析日志。

  • 输出里会直接告诉你哪行malloc没配对free,比如test.c:27
  • 不支持C++的new/delete,也不跟踪mmap/brk等系统调用
  • 如果程序有多个退出路径(比如信号处理、异常分支),确保所有路径都走到exitreturn,否则mtrace日志不全

真正难的不是工具怎么用,而是区分“泄漏”和“glibc内存池暂不归还”。RSS高≠泄漏,得结合pmap[anon]是否持续增长、valgrind是否报definitely lost、以及业务逻辑是否真的该释放——很多所谓“泄漏”,其实是没理解malloc背后那层内存管理器的行为。

本文转载于:https://www.php.cn/faq/3014188.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注