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

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. 使用下面命令, 监控内存变化:

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

如何监控虚拟机内部内存

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

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

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

获取摘要报告

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

使用命令:

shell 复制代码
jcmd <pid> VM.native_memory summary

结果示例:

shell 复制代码
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。

使用命令:

shell 复制代码
jcmd <pid> VM.native_memory detail

结果示例:

shell 复制代码
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命令:

shell 复制代码
jcmd <pid> VM.native_memory baseline

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

shell 复制代码
jcmd <pid> VM.native_memory summary.diff

jcmd <pid> VM.native_memory detail.diff

命令可以带上单位

shell 复制代码
jcmd <pid> VM.native_memory summary.diff scale=MB

summary级别变化报告结果示例

shell 复制代码
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级别变化报告结果示例

shell 复制代码
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)
相关推荐
符哥20089 分钟前
C++ 进阶知识点整理
java·开发语言·jvm
夕除33 分钟前
js--15
java·jvm·spring
4311媒体网3 小时前
C语言操作符全解析 C语言操作符详解
java·c语言·jvm
猫头虎12 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
wgslucky13 小时前
jdk17 配置jvm参数中gc的日志及控制日志数量和大小
jvm·gc·-xlog
痴儿哈哈18 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
野犬寒鸦1 天前
从零起步学习并发编程 || 第七章:ThreadLocal深层解析及常见问题解决方案
java·服务器·开发语言·jvm·后端·学习
闻哥1 天前
Kafka高吞吐量核心揭秘:四大技术架构深度解析
java·jvm·面试·kafka·rabbitmq·springboot
星辰_mya1 天前
Elasticsearch线上问题之慢查询
java·开发语言·jvm
蓝帆傲亦1 天前
代码革命!我用Claude Code 3个月完成1年工作量,这些实战经验全给你
jvm·数据库·oracle