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

别看VIRT或free里的used,盯死RSS(也就是VmRSS)——它代表进程当前真实占用的物理内存页数。泄漏的表现是:无业务增长、无缓存预热、无连接数上升的前提下,RSS持续缓慢爬升;重启后归零,几小时内又回到相同斜率。
那该怎么验证呢?可以用watch -n 30 'ps -p 每隔30秒抓取一次;或者直接读取/proc/里的VmRSS字段,即执行cat /proc/。然后连续观察2到4小时,只有出现单调递增的趋势,才值得深入研究。
RSS涨不等于泄漏——得排除堆外内存(如ByteBuffer.allocateDirect)、JNI调用、或mmap文件映射未释放top里按Shift+M排序后看到的RES列,和ps的rss是同一值,可信RSS稳定但VmSize(虚拟地址空间)持续增大,可能是mmap未munmap,不是传统“malloc泄漏”pmap -x 输出里真正要盯的是Kbytes列和Mapping列。泄漏常表现为[anon]段或[heap]段的大小随时间推移明显变大,尤其是多次执行后发现某段地址范围反复膨胀。
操作建议:
先记下初始值:pmap -x ;
过10–15分钟再跑一次,对比Kbytes变化;
若某[anon]段从1280涨到3840,且没有对应业务动作(如加载大文件、建新连接),基本就是泄漏信号。
pmap -XX 能显示页表级细节,如果看到大量1 page或4KB的[anon]映射,大概率是频繁malloc小块内存却没freepmap本身不报错、不告警,它只反映现状。必须人工比对多个时间点,不能单次快照下结论kill -15让其优雅退出,否则pmap看到的只是运行中快照,无法体现释放行为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可能找不到符号gcc -O0 -g编译,避免优化导致行号错位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:27new/delete,也不跟踪mmap/brk等系统调用exit或return,否则mtrace日志不全真正难的不是工具怎么用,而是区分“泄漏”和“glibc内存池暂不归还”。RSS高≠泄漏,得结合pmap看[anon]是否持续增长、valgrind是否报definitely lost、以及业务逻辑是否真的该释放——很多所谓“泄漏”,其实是没理解malloc背后那层内存管理器的行为。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9