首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >堆外内存泄漏排查方式

堆外内存泄漏排查方式

作者头像
码农戏码
发布2026-06-25 19:59:40
发布2026-06-25 19:59:40
1930
举报

通过 JVM NMT(native memory tracking)来追踪分析堆外内存

只能 Track JVM 自身的内存分配

第三方的 Native 库内存无法 track,不能 Trace JNI 里直接调用 malloc 时的内存分配,典型场景如 ZipInputStream 场景

使用NMT导出内存

代码语言:javascript
复制
jcmd 1 VM.native_memory detail scale=MB > nmt-`date +%F-%H-%M-%S`.log

通过多次导出比较,分析内存的变化。

如果内存没有变化,那需要怀疑是否是堆外的内存变化了

堆外内存使用java工具已经不能胜任。

需要更底层的一些内存分析工具

代码语言:javascript
复制
pmap -x 1 > pmap-`date +%F-%H-%M-%S`.log

两次的内存区别

代码语言:javascript
复制
icdiff pmap-2023-07-27-09-46-36.log pmap-2023-07-28-09-29-55.log | less -SR

查看内存中的具体内容

代码语言:javascript
复制
tail -c +$((0x00007fa9bc000000+1)) /proc/1/mem|head -c $((11616*1024))|strings|less -S

根据pmap-2023-07-27-09-46-36.log 看下RSS占用大小

代码语言:javascript
复制
# 只统计可写权限的内存
awk '/^[0-9a-f].*rw/ { sum += $3 } END { printf "可写内存RSS: %.2f MB\n", sum/1024 }' 1.txt


awk '{ sum += $3 } END { printf "%.2f MB\n", sum/1024 }' 1.txt

strace

向 os 追踪申请内存请求(系统调用),常见用法:

代码语言:javascript
复制
strace -f -e "brk,mmap,munmap" -p pid

堆外内存

1、使用pmap -x {pid} > ./pmap.txt 获取内存映射信息到文件里。

2、使用jcmd ${pid} VM.native_memory detail > nmt.txt获取NMT统计的JVM内存详细信息。

3、找nmt中没有但是在pmap中有的内存块地址(tips1:最好找64MB的内存块)

4、使用上面的dump.sh:./dump.sh {pid} {addr} dump对应内存块的内容到磁盘上。

5、使用 strings {dump文件名} > dumped.txt转换为可读的文本,然后根据文本内容进一步寻找问题的原因

上面的5个步骤可以直接使用 https://github.com/zhuxingsheng/awesome-java-tools 中的 memleak.sh

./memleak.sh show pid

列出可能存在泄漏的内存映射地址:

代码语言:javascript
复制
00007f2824000000   19396   19396   19396 rw---   [ anon ]
00007f28252f1000   46140       0       0 -----   [ anon ]
00007f2830000000    9752    9672    9672 rw---   [ anon ]
00007f2830986000   55784       0       0 -----   [ anon ]
00007f2834000000   11624   11624   11624 rw---   [ anon ]

命令行执行:

./memleak.sh dump pid addr

得到内存块里的内容进一步分析,输出如下:

代码语言:javascript
复制
Dump文件已输出至: ./11983_mem_7f2964000000.bin

最终会产出一个泄漏内存块的文件

这个文件中包含的就是该地址块的内容,但是是二进制的,可以使用如下命令转为字符串方便查看:

代码语言:javascript
复制
strings 11983_mem_7f2964000000.bin > 11983_mem_7f2964000000.bin.txt

Reference

记一次堆外内存泄漏分析[1]

https://juejin.cn/post/7338388292969283584

https://www.cnblogs.com/codelogs/p/17659370.html

Java 进程内存占用及可观测性调研&内存异常排查最佳实践[2]

References

[1] 记一次堆外内存泄漏分析: https://blog.csdn.net/zhuqiuhui/article/details/128513480 [2] Java 进程内存占用及可观测性调研&内存异常排查最佳实践: https://www.pengzna.top/article/Java-Memory/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 堆外内存
  • Reference
    • References
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档