JVM学习-MAT

MAT(Memory Analyzer Tool)
基本概述
  • Java堆内存分析器,可以用于查找内存泄漏以及查看内存消耗情况
  • MAT是基于Eclipse开发的,不仅可以单独使用,还能以插件方式嵌入Eclipse中使用,是一款免费的性能分析工具
获取堆dump文件
  • dump文件内容
    • MAT可以分析heap dump文件,在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就能直观地看到当前的内存信息
    • 这些内存信息包含
      • 所有的对象信息,包括对象实例,成员变量,存储于栈中的基本数据类型值和存储于堆中的其他对象的引用值
      • 所有的类信息,包括classloader、类名称、父类、静态变量等
      • GCRoot到所有的这些对象的引用路径
      • 线程信息,包括线程的调用栈及此线程的线程局部变量(TLS)
  • 获取dump文件
    • 通过jmap工具生成,可以生成任意一个java进程的dump文件
C:\Users\Administrator\IdeaProjects\jvm>jmap -dump:format=b,file=d:\mat\a.hprof 11896
Dumping heap to D:\mat\a.hprof ...
Heap dump file created
  • 通过配置JVM参数生成
    • 选项-XX:+HeapDumpOnOutOfMemoryError 或 -XX:+HeapDumpBeforeFullGC
    • 选项 -XX:HeapDumpPath所代表的含义就是当程序出现OOM时,将会在相应目录下生成一份dump文件,如果不指定,则在当前目录生成dump文件
    • 生产环境中几乎不可能在线对其进行分析,都采用离线分析,因此使用jmap+MAT工具分析dump文件
  • 使用VisualVM可以导出堆dump文件
  • 使用MAT直接从活动Java程序中导出堆快照
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
分析堆dump文件
  • histogram(直方图):展示了各个类的实例数目以及这些实例的shallow heap或retainedheap的总和
  • thread overview
    • 查看系统中的Java线程
    • 查看局部变量的信息
  • 获取对象相互引用的关系
    • with outgoing references
      在这里插入图片描述

    • with incoming references

  • 浅堆与深堆
    • shallow heap(浅堆)
      • 浅堆是指一个对象所消耗的内存,在32位系统中,一个对象引用会占用4个字节,一个int类型会占据4个字节,long型变量占据8字节,每个对象头需要占用8个字节,根据堆快照格式不同,对象的大小可能会向8字节对齐
      • 以String为例:2个int值共占用8个字节,对象引用占用4个字节,对象头8字节,合计20字节,向8字节对齐,故占24字节,这24字节为String对象的浅堆大小,它与String的value实际值无关,无论字符串长度如何,浅堆大小始终是24字节
    • retained heap(深堆)
      • 保留集(Retained Set):对象A的保留集指当对象A被垃圾回收后,可以被释放的所有对象集合(包括对象A本身),即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合,指仅被对象A所持有的对象的集合
      • 深堆:指对象的保留集中所有的对象的浅堆大小之和
      • 注:浅堆指对象本身所占用的内存,不包含其内部引用对象的大小,一个对象的深堆指只能通过该访问到的(直接或间接)所有对象的浅堆之和,即对象被回收,可以释放真实空间
    • 对象实际大小
      • 对象的实际大小定义为一个对象所能触及的所有对象的浅堆大小之和,也就是对象的大小,与深堆相比,这个在日常开发中更为直观和被人接受,但实际这个概念与垃圾回收无关
        在这里插入图片描述
  • 支配树(Dominator Tree)
    • MAT提供了一个称为支配树的对象图,支配树体现了对象实例间的支配关系。在对象引用图中,所有指向对象B的路径都经过A,则认为对象A支配对象B,如果对象A是离对象B最近的一个支配对象,则认为对象A为对象B的直接支配者,支配树是基于对象间的引用图所建立的,它有以下基本特性
      • 对象A的子树表示对象A的保留集,即深堆
      • 如果对象A支配对象B,那么对象A的直接支配者也支配对象B
      • 支配树的边与对象引用图的边不直接对应
    • 下图中,左图表示对象引用图,右图表示左图所对应的支配树,对换A,B由根对象直接支配,由于在到对象C的路径中,可以经过A,也可以经过B,因此对象C的直接支配者也是根对象,对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此,对象D是对象F的直接支配者,而到对象D的所有路径中,必须经过C,即从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以,对象D的直接支配者为对象C,同理,对象E支配对象G,到达对象H可以通过对象D,也可以通过对象E,因此对象D和E都不能支配对象H,而经过对象C既可到达D也可到达E,因此对象C为对象H的直接支配者
      在这里插入图片描述
OQL(Object Query Language)
  • MAT支持一种类似于SQL的查询语言OQL(Object Query Language),OQL使用类SQL语法,可以在堆中进行对象的查找和筛选
  • SELECT子句
    • 在MAT中,Select子句的格式与SQL基本一致,用于指定要显示的列,Select子句中可以使用*,查看结果对象的引用实例(相当于outgoing references)。

    • SELECT * FROM java.util.Vector v
      在这里插入图片描述

    • 使用OBJECTS关键字,可以将返回结果集中的项以对象的形式显示

    • SELECT objects v.elementData FROM java.util.Vector v || SELECT OBJECTS s.value FROM java.lang.String s
      在这里插入图片描述

    • 在Select子句中,使用AS RETAINED SET关键字可以得到所得对象的保留集

    • SELECT AS RETAINED SET * FROM com.chapter11.Student

    • DISTINCT关键字用于在结果集中去除重复对象

    • SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s

  • FROM子句
    • From子句用于指定查询范围,它可以指定类名、正则表达式或者对象地址
  • WHERE子句
    • where子句用于指定OQL的查询条件,OQL查询将只返回满足where子句指定条件的对象
    • where支持多个条件AND、OR运算
  • 内置对象与方法
    • OQL可以访问堆内对象的属性,也可以访问堆内代理对象的属性,访问堆内对象的属性时格式:[.]..
    • 其中alias为对象名称
<think>好的,用户现在问的是关于JVM参数-XX:+HeapDumpOnOutOfMemoryError的详细介绍。首先,我需要回想一下这个参数的作用。记得这个参数是在JVM发生内存溢出(OOM)时自动生成堆转储文件,也就是Heap Dump。这样可以帮助开发人员分析内存泄漏或者内存使用过高的原因。 接下来,我需要考虑用户可能的背景。用户可能遇到了OOM的问题,或者正在学习如何调优JVM,想要了解如何配置以方便故障排查。他们可能是开发人员或者运维人员,需要处理生产环境中的内存问题。因此,回答需要既详细又实用,包括如何设置参数、生成的文件位置分析工具等。 然后,要确定用户可能没有明确提到的需求。比如,用户可能不仅想知道这个参数的作用,还想知道如何使用生成的Heap Dump文件,以及相关的其他参数,比如指定转储文件路径的-XX:HeapDumpPath。此外,可能还需要对比其他相关参数或方法,比如手动生成Heap Dump的方式,或者结合其他JVM参数进行内存分析。 我需要确保回答结构清晰,分点列出核心作用、使用方法、文件分析工具、注意事项等。同时,要给出实际的示例命令,方便用户直接复制使用。还要注意提醒用户生成Heap Dump可能带来的性能影响,尤其是在生产环境中需要权衡利弊。 另外,用户可能需要知道如何分析生成的Heap Dump文件,所以需要推荐一些常用工具,比如Eclipse MAT、VisualVM等,并简要说明使用方法。还要提到即使设置了参数,在某些情况下可能无法生成Heap Dump的情况,比如磁盘空间不足或权限问题,这样帮助用户避免常见陷阱。 最后,总结这个参数的重要性和适用场景,强调它在故障排查中的价值,同时提醒配合其他JVM参数使用,比如-XX:HeapDumpPath和-XX:OnOutOfMemoryError来执行自定义脚本,增强问题处理能力。</think>### JVM参数 `-XX:+HeapDumpOnOutOfMemoryError` 详解 --- #### **核心作用** 当JVM触发 **`OutOfMemoryError`(内存溢出)** 时,自动生成 **堆转储文件(Heap Dump)**,记录内存崩溃瞬间的堆内存快照。该文件是分析内存泄漏或内存消耗异常的 **关键证据**。 --- #### **参数用法** 1. **基本启用** 在JVM启动参数中添加: ```bash -XX:+HeapDumpOnOutOfMemoryError ``` 2. **指定转储路径**(配合 `-XX:HeapDumpPath`) ```bash -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps/heapdump.hprof ``` - 路径可以是目录(自动生成文件名)或完整文件路径 - 示例文件名:`java_pid12345_20240320.hprof`(含进程ID和时间戳) --- #### **典型应用场景** 1. **生产环境故障排查** 内存溢出时自动保留“案发现场”,避免重启后丢失关键信息。 2. **性能调优** 通过分析堆转储文件定位内存消耗过高的对象(如缓存未释放、大数组等)。 3. **偶发性问题捕捉** 捕获难以复现的间歇性内存泄漏问题。 --- #### **堆转储文件分析工具** | 工具名称 | 特点 | |------------------|----------------------------------------------------------------------| | **Eclipse MAT** | 内存分析神器,可视化对象依赖树,支持泄漏检测报告(需安装JDK) | | **VisualVM** | JDK自带工具,支持堆转储基础分析(命令行输入 `jvisualvm` 启动) | | **jhat** | 命令行工具,生成HTML报告(示例:`jhat heapdump.hprof`) | | **YourKit** | 商业工具,深度分析内存分配和线程状态 | --- #### **实战配置示例** ```bash java -Xmx512m \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath=/var/log/myapp/oom_dumps \ -jar my-application.jar ``` - `-Xmx512m`:设置堆最大内存为512MB(更容易触发OOM测试) - 生成的转储文件会保存在 `/var/log/myapp/oom_dumps` 目录 --- #### **注意事项** 1. **磁盘空间** 堆转储文件大小通常与堆内存最大值相当(例如4GB的堆可能生成3GB的.hprof文件)。 2. **性能影响** 生成堆转储时JVM会暂停(STW),生产环境需评估对服务的影响。 3. **权限问题** 确保JVM进程对输出目录有写入权限,否则会静默失败。 4. **OOM类型** 仅对 `java.lang.OutOfMemoryError` 有效,其他错误(如栈溢出)不会触发转储。 --- #### **高级技巧** 1. **组合使用 `-XX:OnOutOfMemoryError`** 内存溢出时执行自定义脚本(如发送告警、重启服务): ```bash -XX:OnOutOfMemoryError="/opt/scripts/restart_service.sh" ``` 2. **压缩转储文件**(第三方工具) 使用 `gzip` 压缩节省空间(需手动处理): ```bash find /dump_dir -name "*.hprof" -exec gzip {} \; ``` 3. **自动化分析** 结合持续集成工具,自动解析堆转储并生成报告(需编写脚本)。 --- #### **手动生成堆转储** 即使未启用该参数,仍可通过以下方式获取堆转储: 1. **jmap命令** ```bash jmap -dump:format=b,file=heap.hprof <pid> ``` 2. **JVM信号触发** ```bash kill -3 <pid> # Linux/Mac ``` --- #### **关键总结** - **核心价值**:内存溢出时自动保留“内存快照”,极大提升问题诊断效率。 - **必配场景**:生产环境JVM强烈建议启用此参数。 - **分析要点**:重点关注重复创建的巨型对象、未释放的集合类(如HashMap、ArrayList)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值