当前位置: 首页 > news >正文

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

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

文章目录

  • JVM本地内存的使用监控情况
    • NMT跟踪的内存
    • 使用 NMT 检测内存泄漏
    • 如何监控虚拟机内部内存
      • 获取摘要报告
      • 查询详细报告
      • 查询跟踪变化报告

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

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

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

NMT跟踪的内存

本机内存跟踪内存类别

类别说明
Java HeapThe heap where your objects live 对象所在的堆的内存使用情况
ClassClass meta data 元数据区使用的内存情况
CodeGenerated code JIT产生的汇编指令所占的空间情况
GCdata use by the GC, such as card table 由GC使用的内存情况,如card table
CompilerMemory used by the compiler when generating code 编译器在生成代码时使用的内存情况
SymbolSymbols 符号,如同String table和常量池
Memory TrackingMemory used by NMT itself NMT本身使用的内存
Pooled Free ChunksMemory used by chunks in the arena chunk pool chunks 池中块使用的内存
Shared space for classesMemory mapped to class data sharing archive 内存映射到类数据共享归档
ThreadMemory used by threads, including thread data structure, resource area and handle area and so on. 线程使用的内存,包括线程数据结构、资源区和句柄区等。
Thread stackThread stack. It is marked as committed memory, but it might not be completely committed by the OS 线程栈。 它被标记为已提交内存,但操作系统可能不会完全提交它
InternalMemory that does not fit the previous categories, such as the memory used by the command line parser, JVMTI, properties and so on. 不属于前几类的内存,如命令行解析器、JVMTI、属性等使用的内存。
UnknownWhen 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 Stackfrom [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 Stackfrom [Thread::record_stack_base_and_size()+0xca][0x8f585000 - 0x8f729000] committed 1680KB from [Thread::record_stack_base_and_size()+0xca][0x8f930000 - 0x90100000] reserved 8000KB for GCfrom [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 GCfrom [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 Stackfrom [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 rangefrom [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 Stackfrom [Thread::record_stack_base_and_size()+0xca][0xb0c61000 - 0xb0ce2000] committed 516KB from [Thread::record_stack_base_and_size()+0xca][0xb0ce2000 - 0xb0e83000] reserved 1668KB for GCfrom [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 Codefrom [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 Classfrom [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 Internalfrom [PerfMemory::create_memory_region(unsigned int)+0x8ba][0xb770b000 - 0xb775c000] reserved 324KB for Thread Stackfrom [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.diffjcmd <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)
http://www.lryc.cn/news/582901.html

相关文章:

  • JVM 为什么使用元空间(Metaspace)替换了永久代(PermGen)?——深入理解 Java 方法区与类元数据存储的演进
  • 征程 6|工具链量化简介与代码实操
  • Redis 缓存进阶篇,缓存真实数据和缓存文件指针最佳实现?如何选择?
  • 当Powerbi遇到quickbi,性能优化方式对比
  • 玩具语音方案选型决策OTP vs Flash 的成本功耗与灵活性
  • BERT代码简单笔记
  • 台式电脑如何连wifi 快速连接方法
  • 无缝高清矩阵与画面分割器的区别
  • numpy数据分析知识总结
  • Web前端:not(否定伪类选择器)
  • boost中boost::noncopyalbe和boost::ignore_unused的使用详解和实战示例
  • 网络--初级
  • NestJS 系列教程(四):中间件、中断器与异常过滤器详解
  • 17-C#的socket通信TCP-1
  • 【python】 time_str = time_str.strip() 与 time_str = str(time_str).strip() 的区别
  • Spring Batch终极指南:原理、实战与性能优化
  • 开源 python 应用 开发(四)python文件和系统综合应用
  • ${project.basedir}延申出来的Maven内置的一些常用属性
  • Linux 第一个系统程序 - 进度条
  • 基于springboot的物流配货系统
  • 内网服务器怎么设置公网远程访问? windows桌面连接和Linux自带SSH外网异地跨网用完整步骤教程
  • JK触发器Multisim电路仿真——硬件工程师笔记
  • 【读论文】GLM-4.1V-Thinking 解读:用强化学习解锁 VLM 的通用推理能力
  • 进程于线程 -1
  • 小架构step系列08:logback.xml的配置
  • 数据提取之lxml模块与xpath工具
  • LLM探索的时代
  • 大学数字经济专业课程介绍
  • maven 发布到中央仓库之持续集成-03
  • 无缝矩阵支持音频分离带画面分割功能的全面解析