JNI层malloc内存在jcmd VM.native_memory中归属哪类?
JNI malloc内存的jcmd统计分类与RSS异常分析
关于jcmd VM.native_memory的统计分类
JNI层通过malloc直接分配的内存,不会被统计到Internal或Arena分类中。这两个分类仅追踪JVM自身内部运作产生的内存开销(比如JVM的管理数据结构、即时编译器的临时内存、垃圾回收的辅助内存等),而JNI调用标准C库分配的内存属于进程级原生内存,不在JVM的主动追踪范围内。
RSS远大于Java堆内存的原因排查
程序堆内存仅150M但RSS达17G,JNI层的malloc内存是核心怀疑对象,原因如下:
- RSS统计的是进程整个地址空间的实际物理内存占用,包含Java堆、元空间、JVM内部原生内存、JNI分配的原生内存、加载的共享库内存等多个部分,Java堆只是其中之一。
- 如果JNI代码中存在大量
malloc调用且未正确释放(内存泄漏),会快速累积大量原生内存,直接推高RSS数值。
验证方法:
- 使用系统工具
pmap分析进程的内存块分布,定位大内存区域的来源; - 在JNI代码中添加内存分配与释放的日志,跟踪内存申请和回收的全流程;
- 执行
jcmd VM.native_memory detail,将输出中所有JVM统计的原生内存总和与RSS对比,两者的差值基本就是JNI分配的内存(以及其他未被JVM追踪的原生内存)。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

