JVM本地内存的使用监控情况

发布于:2025-07-10 ⋅ 阅读:(21) ⋅ 点赞:(0)

JVM本地内存的使用监控情况


NMT,全称为Native Memory Tracking,是Java 8u40版本引入的一项功能,用于跟踪JVM本身在本地内存中的内存使用情况。

NMT 不支持跟踪非 JVM 代码的内存分配,需要使用操作系统支持的工具来检测本地代码中的内存泄漏。

启用 NMT 会导致 JVM 性能下降 5%~10%,并且NMT的内存使用将在所有malloc内存中添加2个机器字作为malloc头。

NMT跟踪的内存

本机内存跟踪内存类别

类别 说明
Java Heap The heap where your objects live 对象所在的堆的内存使用情况
Class Class meta data 元数据区使用的内存情况
Code Generated code JIT产生的汇编指令所占的空间情况
GC data use by the GC, such as card table 由GC使用的内存情况,如card table
Compiler Memory used by the compiler when generating code 编译器在生成代码时使用的内存情况
Symbol Symbols 符号,如同String table和常量池
Memory Tracking Memory used by NMT itself NMT本身使用的内存
Pooled Free Chunks Memory used by chunks in the arena chunk pool chunks 池中块使用的内存
Shared space for classes Memory mapped to class data sharing archive 内存映射到类数据共享归档
Thread Memory used by threads, including thread data structure, resource area and handle area and so on. 线程使用的内存,包括线程数据结构、资源区和句柄区等。
Thread stack Thread stack. It is marked as committed memory, but it might not be completely committed by the OS 线程栈。 它被标记为已提交内存,但操作系统可能不会完全提交它
Internal Memory that does not fit the previous categories, such as the memory used by the command line parser, JVMTI, properties and so on. 不属于前几类的内存,如命令行解析器、JVMTI、属性等使用的内存。
Unknown When memory category can not be determined.Arena: When arena is used as a stack or value objectVirtual Memory: When type information has not yet arrived 当无法确定内存类别时: 当arena 被用作堆栈或值对象时虚拟内存: 当类型信息尚未统计到时

使用 NMT 检测内存泄漏

  1. 启动Java程序时,需要增加下列命令行选项:-XX:NativeMemoryTracking=summary-XX:NativeMemoryTracking=detail,以summary或detail跟踪方式启动 JVM。

  2. 建立早期基线–使用 NMT base功能获得基线,以便在开发和维护期间进行比较,方法是运行:

    jcmd <pid> VM.native_memory baseline
    
  3. 使用下面命令, 监控内存变化:

     jcmd <pid> VM.native_memory detail.diff
    
  4. 如果应用程序泄漏了少量内存,则需要运行一段时间才能显示出来。

如何监控虚拟机内部内存

Arena 是使用 malloc 分配的一大块内存。在退出作用域或离开代码区域时,会从这些内存块中批量释放内存。这些内存块可在其他子系统中重复使用,以保存临时内存,例如线程前分配。Arena 的 malloc 策略可确保无内存泄漏。因此,Arena 将作为一个整体而非单个对象进行跟踪。有些初始内存是无法跟踪的。

jcmd 实用程序一起使用时,可以查询空间情况。

下文将介绍如何获取 NMT 的摘要或详细数据,以及如何解释示例输出。

获取摘要报告

前提:使用命令行选项 -XX:NativeMemoryTracking=summary启动 JVM。

使用命令:

jcmd <pid> VM.native_memory summary

结果示例:

Total:  reserved=664192KB,  committed=253120KB                                           <--- total memory tracked by Native Memory Tracking
 
-                 Java Heap (reserved=516096KB, committed=204800KB)                      <--- Java Heap
                            (mmap: reserved=516096KB, committed=204800KB)
 
-                     Class (reserved=6568KB, committed=4140KB)                          <--- class metadata
                            (classes #665)                                               <--- number of loaded classes
                            (malloc=424KB, #1000)                                        <--- malloc'd memory, #number of malloc
                            (mmap: reserved=6144KB, committed=3716KB)
 
-                    Thread (reserved=6868KB, committed=6868KB)
                            (thread #15)                                                 <--- number of threads
                            (stack: reserved=6780KB, committed=6780KB)                   <--- memory used by thread stacks
                            (malloc=27KB, #66)
                            (arena=61KB, #30)                                            <--- resource and handle areas
 
-                      Code (reserved=102414KB, committed=6314KB)
                            (malloc=2574KB, #74316)
                            (mmap: reserved=99840KB, committed=3740KB)
 
-                        GC (reserved=26154KB, committed=24938KB)
                            (malloc=486KB, #110)
                            (mmap: reserved=25668KB, committed=24452KB)
 
-                  Compiler (reserved=106KB, committed=106KB)
                            (malloc=7KB, #90)
                            (arena=99KB, #3)
 
-                  Internal (reserved=586KB, committed=554KB)
                            (malloc=554KB, #1677)
                            (mmap: reserved=32KB, committed=0KB)
 
-                    Symbol (reserved=906KB, committed=906KB)
                            (malloc=514KB, #2736)
                            (arena=392KB, #1)
 
-           Memory Tracking (reserved=3184KB, committed=3184KB)
                            (malloc=3184KB, #300)
 
-        Pooled Free Chunks (reserved=1276KB, committed=1276KB)
                            (malloc=1276KB)
 
-                   Unknown (reserved=33KB, committed=33KB)
                            (arena=33KB, #1)

查询详细报告

前提:使用命令行选项 -XX:NativeMemoryTracking=detail启动 JVM。

使用命令:

jcmd <pid> VM.native_memory detail

结果示例:

Virtual memory map:
 
[0x8f1c1000 - 0x8f467000] reserved 2712KB for Thread Stack
                from [Thread::record_stack_base_and_size()+0xca]
        [0x8f1c1000 - 0x8f467000] committed 2712KB from [Thread::record_stack_base_and_size()+0xca]
 
[0x8f585000 - 0x8f729000] reserved 1680KB for Thread Stack
                from [Thread::record_stack_base_and_size()+0xca]
        [0x8f585000 - 0x8f729000] committed 1680KB from [Thread::record_stack_base_and_size()+0xca]
 
[0x8f930000 - 0x90100000] reserved 8000KB for GC
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x555]
        [0x8f930000 - 0x90100000] committed 8000KB from [PSVirtualSpace::expand_by(unsigned int)+0x95]
 
[0x902dd000 - 0x9127d000] reserved 16000KB for GC
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x555]
        [0x902dd000 - 0x9127d000] committed 16000KB from [os::pd_commit_memory(char*, unsigned int, unsigned int, bool)+0x36]
 
[0x9127d000 - 0x91400000] reserved 1548KB for Thread Stack
                from [Thread::record_stack_base_and_size()+0xca]
        [0x9127d000 - 0x91400000] committed 1548KB from [Thread::record_stack_base_and_size()+0xca]
 
[0x91400000 - 0xb0c00000] reserved 516096KB for Java Heap                                                                            <--- reserved memory range
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x190]                  <--- callsite that reserves the memory
        [0x91400000 - 0x93400000] committed 32768KB from [VirtualSpace::initialize(ReservedSpace, unsigned int)+0x3e8]               <--- committed memory range and its callsite
        [0xa6400000 - 0xb0c00000] committed 172032KB from [PSVirtualSpace::expand_by(unsigned int)+0x95]                             <--- committed memory range and its callsite
 
[0xb0c61000 - 0xb0ce2000] reserved 516KB for Thread Stack
                from [Thread::record_stack_base_and_size()+0xca]
        [0xb0c61000 - 0xb0ce2000] committed 516KB from [Thread::record_stack_base_and_size()+0xca]
 
[0xb0ce2000 - 0xb0e83000] reserved 1668KB for GC
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x555]
        [0xb0ce2000 - 0xb0cf0000] committed 56KB from [PSVirtualSpace::expand_by(unsigned int)+0x95]
        [0xb0d88000 - 0xb0d96000] committed 56KB from [CardTableModRefBS::resize_covered_region(MemRegion)+0xebf]
        [0xb0e2e000 - 0xb0e83000] committed 340KB from [CardTableModRefBS::resize_covered_region(MemRegion)+0xebf]
 
[0xb0e83000 - 0xb7003000] reserved 99840KB for Code
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x555]
        [0xb0e83000 - 0xb0e92000] committed 60KB from [VirtualSpace::initialize(ReservedSpace, unsigned int)+0x3e8]
        [0xb1003000 - 0xb139b000] committed 3680KB from [VirtualSpace::initialize(ReservedSpace, unsigned int)+0x37a]
 
[0xb7003000 - 0xb7603000] reserved 6144KB for Class
                from [ReservedSpace::initialize(unsigned int, unsigned int, bool, char*, unsigned int, bool)+0x555]
        [0xb7003000 - 0xb73a4000] committed 3716KB from [VirtualSpace::initialize(ReservedSpace, unsigned int)+0x37a]
 
[0xb7603000 - 0xb760b000] reserved 32KB for Internal
                from [PerfMemory::create_memory_region(unsigned int)+0x8ba]
 
[0xb770b000 - 0xb775c000] reserved 324KB for Thread Stack
                from [Thread::record_stack_base_and_size()+0xca]
        [0xb770b000 - 0xb775c000] committed 324KB from [Thread::record_stack_base_and_size()+0xca]

查询跟踪变化报告

对于summary和detail级别的跟踪,可以在应用程序启动并运行后设置基线。设置baseline命令:

jcmd <pid> VM.native_memory baseline

查询不同级别变化报告命令

jcmd <pid> VM.native_memory summary.diff

jcmd <pid> VM.native_memory detail.diff

命令可以带上单位

jcmd <pid> VM.native_memory summary.diff scale=MB

summary级别变化报告结果示例

Total:  reserved=664624KB  -20610KB, committed=254344KB -20610KB                         <--- total memory changes vs. earlier baseline. '+'=increase '-'=decrease
 
-                 Java Heap (reserved=516096KB, committed=204800KB)
                            (mmap: reserved=516096KB, committed=204800KB)
 
-                     Class (reserved=6578KB +3KB, committed=4530KB +3KB)
                            (classes #668 +3)                                            <--- 3 more classes loaded
                            (malloc=434KB +3KB, #930 -7)                                 <--- malloc'd memory increased by 3KB, but number of malloc count decreased by 7
                            (mmap: reserved=6144KB, committed=4096KB)
 
-                    Thread (reserved=60KB -1129KB, committed=60KB -1129KB)
                            (thread #16 +1)                                              <--- one more thread
                            (stack: reserved=7104KB +324KB, committed=7104KB +324KB)
                            (malloc=29KB +2KB, #70 +4)
                            (arena=31KB -1131KB, #32 +2)                                 <--- 2 more arenas (one more resource area and one more handle area)
 
-                      Code (reserved=102328KB +133KB, committed=6640KB +133KB)
                            (malloc=2488KB +133KB, #72694 +4287)
                            (mmap: reserved=99840KB, committed=4152KB)
 
-                        GC (reserved=26154KB, committed=24938KB)
                            (malloc=486KB, #110)
                            (mmap: reserved=25668KB, committed=24452KB)
 
-                  Compiler (reserved=106KB, committed=106KB)
                            (malloc=7KB, #93)
                            (arena=99KB, #3)
 
-                  Internal (reserved=590KB +35KB, committed=558KB +35KB)
                            (malloc=558KB +35KB, #1699 +20)
                            (mmap: reserved=32KB, committed=0KB)
 
-                    Symbol (reserved=911KB +5KB, committed=911KB +5KB)
                            (malloc=519KB +5KB, #2921 +180)
                            (arena=392KB, #1)
 
-           Memory Tracking (reserved=2073KB -887KB, committed=2073KB -887KB)
                            (malloc=2073KB -887KB, #84 -210)
 
-        Pooled Free Chunks (reserved=2624KB -15876KB, committed=2624KB -15876KB)
                            (malloc=2624KB -15876KB)

Details级别变化报告结果示例

Details:
 
[0x01195652] ChunkPool::allocate(unsigned int)+0xe2
                            (malloc=482KB -481KB, #8 -8)
 
[0x01195652] ChunkPool::allocate(unsigned int)+0xe2
                            (malloc=2786KB -19742KB, #134 -618)
 
[0x013bd432] CodeBlob::set_oop_maps(OopMapSet*)+0xa2
                            (malloc=591KB +6KB, #681 +37)
 
[0x013c12b1] CodeBuffer::block_comment(int, char const*)+0x21                <--- [callsite address] method name + offset
                            (malloc=562KB +33KB, #35940 +2125)               <--- malloc'd amount, increased by 33KB #malloc count, increased by 2125
 
[0x0145f172] ConstantPool::ConstantPool(Array<unsigned char>*)+0x62
                            (malloc=69KB +2KB, #610 +15)
 
...
 
[0x01aa3ee2] Thread::allocate(unsigned int, bool, unsigned short)+0x122
                            (malloc=21KB +2KB, #13 +1)
 
[0x01aa73ca] Thread::record_stack_base_and_size()+0xca
                            (mmap: reserved=7104KB +324KB, committed=7104KB +324KB)

网站公告

今日签到

点亮在社区的每一天
去签到