关于 堆外内存的组成可以看上一篇文章 JVM 堆外内存泄漏分析(一)
1. NMT
NMT(Native Memory Tracking)是 HotSpot JVM 引入的跟踪 JVM 内部使用的本地内存的一个特性,可以通过 jcmd 工具访问 NMT 数据。NMT 目前不支持跟踪第三方本地代码的内存分配和 JDK 类库。
NMT 不跟踪非 JVM 代码的内存分配,本地代码里的内存泄露需要使用操作系统支持的工具来定位。
1.1 开启 NMT
启用 NMT 会带来 5-10% 的性能损失。NMT 的内存使用率情况需要添加两个机器字 word 到 malloc 内存的 malloc 头里。NMT 内存使用率也被 NMT 跟踪。
启动命令: -XX:NativeMemoryTracking=[off | summary | detail]
。
off:NMT 默认是关闭的;
summary:只收集子系统的内存使用的总计数据;
detail:收集每个调用点的内存使用数据。
1.2 jcmd 访问 NMT 数据
命令: jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
option | desc |
---|---|
summary | 按分类打印汇总数据 |
detail | 按分类打印汇总数据 打印虚拟内存映射 按调用点打印内存使用汇总 |
baseling | 创建内存使用快照用于后续对比 |
summary.diff | 基于最新的基线打印一份汇总报告 |
detail.diff | 基于最新的基线打印一份明细报告 |
shutdown | 关闭 NMT |
在 NMT 启用的情况下,可以通过下面的命令行选项在 JVM 退出时输出最后的内存使用数据:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics