排查Java的内存问题(8)

0000000100000000 8K r-x-- /sw/.es-base/sparc/pkg/jdk-1.7.0_60/bin/sparcv9/java
0000000100100000 8K rwx-- /sw/.es-base/sparc/pkg/jdk-1.7.0_60/bin/sparcv9/java
0000000100102000 56K rwx--    [ heap ]
0000000100110000 2624K rwx-- [ heap ]  <--- native Heap
00000001FB000000 24576K rw--- [ anon ]  <--- Java Heap starts here
0000000200000000 1396736K rw--- [ anon ]
0000000600000000 700416K rw--- [ anon ]

这个问题可以通过-XX:HeapBaseMinAddress=n选项来解决,它能指定Java堆的起始地址。将它的设置成一个更高的地址将会为原生堆留出更多的空间。

关于如何诊断、排查和解决该问题,请参阅该文了解更详细的信息。

原生堆:诊断工具

让我们看一下内存泄露的探查工具,它们能够帮助我们找到原生内存泄露的原因。

原生内存跟踪

JVM有一个强大的特性叫做原生内存跟踪(Native Memory Tracking,NMT),它在JVM内部用来跟踪原生内存。需要注意的是,它无法跟踪JVM之外或原生库分配的内存。通过下面两个简单的步骤,我们就可以监控JVM的原生内存使用情况:

以启用NMT的方式启动进程。输出级别可以设置为“summary”或“detail”级别:

-XX:NativeMemoryTracking=summary

-XX:NativeMemoryTracking=detail

使用jcmd来获取原生内存使用的细节:

jcmd <pid> VM.native_memory  

NMT输出的样例:

d:\tests>jcmd 90172 VM.native_memory  90172:
Native Memory Tracking:
Total: reserved=3431296KB, committed=2132244KB
-                Java Heap (reserved=2017280KB, committed=2017280KB)
            (mmap: reserved=2017280KB, committed=2017280KB)
-                Class (reserved=1062088KB, committed=10184KB)
            (classes #411)
            (malloc=5320KB #190)
            (mmap: reserved=1056768KB, committed=4864KB)
-                  Thread (reserved=15423KB, committed=15423KB)
            (thread #16)
            (stack: reserved=15360KB, committed=15360KB)
            (malloc=45KB #81)
            (arena=18KB #30)
-                Code (reserved=249658KB, committed=2594KB)
            (malloc=58KB #348)
            (mmap: reserved=249600KB, committed=2536KB)
-                GC (reserved=79628KB, committed=79544KB)
            (malloc=5772KB #118)
            (mmap: reserved=73856KB, committed=73772KB)
-                Compiler (reserved=138KB, committed=138KB)
            (malloc=8KB #41)
            (arena=131KB #3)
-                Internal (reserved=5380KB, committed=5380KB)
            (malloc=5316KB #1357)
            (mmap: reserved=64KB, committed=64KB)
-                Symbol (reserved=1367KB, committed=1367KB)
            (malloc=911KB #112)
            (arena=456KB #1)
-                Native Memory Tracking (reserved=118KB, committed=118KB)
            (malloc=66KB #1040)
            (tracking overhead=52KB)
-                Arena Chunk (reserved=217KB, committed=217KB)
            (malloc=217KB)

关于使用jcmd命令访问NMT数据的细节以及如何阅读它的输出,可以参见该文

原生内存泄露探查工具

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8897945a0be00fadb00880f35eefe05e.html