前面的文章详细讲述了分析Thread Dump文件,实际在处理Java内存泄漏问题的时候,还需要分析JVM堆转储文件来进行定位。
JVM故障分析及性能优化实战:
JVM故障分析及性能优化实战(I)——使用jstack定位线程堆栈信息
JVM故障分析及性能优化实战(II)——jstack生成的Thread Dump日志结构解析
JVM故障分析及性能优化实战(III)——jstat命令的使用及VM Thread分析
JVM故障分析及性能优化实战(IV)——jstack生成的Thread Dump日志线程状
JVM故障分析及性能优化实战(V)——常见的Thread Dump日志案例分析
目录
1 JVM Heap Dump(堆转储文件)的生成
1.1 使用 jmap 命令生成
1.2 使用 JConsole 生成
1.3 在JVM中增加参数生成
2 常见的Heap Dump文件分析工具
2.1 jhat
2.2 Eclipse Memory Analyzer(MAT)
2.3 IBM Heap Analyzer
3 Memory Analyzer的安装和使用
3.1 下载与安装
3.2 主界面
3.3 Overview
3.4 Histogram
3.5 Dominator Tree
3.6 OQL
3.7 Thread Overview
3.8 Run Expert System Test
3.9 Open Query Browser
3.10 Find Object by address
JVM Heap Dump(堆转储文件)的生成
正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了JVM中堆内存运行的情况。
可以通过以下几种方式生成Heap Dump文件:
使用 jmap 命令生成
jmap [https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html\] 命令是JDK提供的用于生成堆内存信息的工具,可以执行下面的命令生成Heap Dump:
jmap -dump:live,format=b,file=heap-dump.bin <pid>
其中的pid是JVM进程的id(可以通过jps命令获取pid),heap-dump.bin
是生成的文件名称,在执行命令的目录下面。推荐此种方法。
使用 JConsole 生成
JConsole是JDK提供的一个基于GUI查看JVM系统信息的工具,既可以管理本地的JVM,也可以管理远程的JVM,可以通过下图的 dumpHeap
按钮生成 Heap Dump文件。
在JVM中增加参数生成
在JVM的配置参数中可以添加 -XX:+HeapDumpOnOutOfMemoryError
参数,当应用抛出 OutOfMemoryError 时自动生成dump文件;
在JVM的配置参数中添加 -Xrunhprof:head=site
参数,会生成java.hprof.txt 文件,不过这样会影响JVM的运行效率,不建议在生产环境中使用(未亲测)。
常见的Heap Dump文件分析工具
JVM Heap Dump文件可以使用常用的分析工具如下:
jhat
jhat [https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jhat.html\] 是JDK自带的用于分析JVM Heap Dump文件的工具,使用下面的命令可以将堆文件的分析结果以HTML网页的形式进行展示:
jhat <heap-dump-file>
其中 heap-dump-file 是文件的路径和文件名,可以使用 -J-Xmx512m
参数设置命令的内存大小。执行成功之后显示如下结果:
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
这个时候访问 http://localhost:7000/ 就可以看到结果了。
Eclipse Memory Analyzer(MAT)
Eclipse Memory Analyzer(MAT) [https://www.eclipse.org/mat/\] 是Eclipse提供的一款用于Heap Dump文件的工具,操作简单明了,下面将详细进行介绍。
IBM Heap Analyzer
IBM Heap Analyzer [https://www.ibm.com/developerworks/community/alphaworks/tech/heapanalyzer\] 是IBM公司推出的一款用于分析Heap Dump信息的工具,下载之后是一个jar文件,执行结果如下:
Memory Analyzer的安装和使用
如前文所述,Eclipse Memory Analyzer(简称MAT)是一个功能丰富且操作简单的JVM Heap Dump分析工具,可以用来辅助发现内存泄漏减少内存占用。
使用 Memory Analyzer 来分析生产环境的 Java 堆转储文件,可以从数以百万计的对象中快速计算出对象的 Retained Size,查看是谁在阻止垃圾回收,并自动生成一个 Leak Suspect(内存泄露可疑点)报表。
下载与安装
Eclipse Memory Analyzer(MAT)支持两种安装方式,一是Eclipse插件的方式,另外一个就是独立运行的方式,建议使用独立运行的方式。
在 http://www.eclipse.org/mat/downloads.php 下载安装MAT,启动之后打开 File - Open Heap Dump... 菜单,然后选择生成的Heap DUmp文件,选择 "Leak Suspects Report",然后点击 "Finish" 按钮。
主界面
第一次打开因为需要分析dump文件,所以需要等待一段时间进行分析,分析完成之后dump文件目录下面的文件信息如下:
上图中 heap-27311.bin 文件是原始的Heap Dump文件,zip文件是生成的html形式的报告文件。
打开之后,主界面如下所示:
接下来介绍界面中常用到的功能:
Overview
Overview视图,即概要界面,显示了概要的信息,并展示了MAT常用的一些功能。
Details 显示了一些统计信息,包括整个堆内存的大小、类(Class)的数量、对象(Object)的数量、类加载器(Class Loader)的数量。
Biggest Objects by Retained Size 使用饼图的方式直观地显示了在JVM堆内存中最大的几个对象,当光标移到饼图上的时候会在左边Inspector和Attributes窗口中显示详细的信息。
Actions 这里显示了几种常用到的操作,算是功能的快捷方式,包括 Histogram、Dominator Tree、Top Consumers、Duplicate Classes,具体的含义和用法见下面;
Reports 列出了常用的报告信息,包括 Leak Suspects和Top Components,具体的含义和内容见下;
Step By Step 以向导的方式引导使用功能。
Histogram
直方图,可以查看每个类的实例(即对象)的数量和大小。
Dominator Tree
支配树,列出Heap Dump中处于活跃状态中的最大的几个对象,默认按 retained size进行排序,因此很容易找到占用内存最多的对象。
OQL
MAT提供了一个对象查询语言(OQL),跟SQL语言类似,将类当作表、对象当作记录行、成员变量当作表中的字段。通过OQL可以方便快捷的查询一些需要的信息,是一个非常有用的工具。
Thread Overview
此工具可以查看生成Heap Dump文件的时候线程的运行情况,用于线程的分析。
Run Expert System Test
可以查看分析完成的HTML形式的报告,也可以打开已经产生的分析报告文件,子菜单项如下图所示:
常用的主要有Leak Suspects和Top Components两种报告:
Leak Suspects 可以说是非常常用的报告了,该报告分析了 Heap Dump并尝试找出内存泄漏点,最后在生成的报告中对检测到的可疑点做了详细的说明;
Top Components 列出占用总堆内存超过1%的对象。
Open Query Browser
提供了在分析过程中用到的工具,通常都集成在了右键菜单中,在后面具体举例分析的时候会做详细的说明。如下图:
这里仅针对在 Overview 界面中的 Acations中列出的两项进行说明:
Top Consumers 按类、类加载器和包分别进行查询,并以饼图的方式列出最大的几个对象。菜单打开方式如下:
Duplicate Classes 列出被加载多次的类,结果按类加载器进行分组,目标是加载同一个类多次被类加载器加载。使用该工具很容易找到部署应用的时候使用了同一个库的多个版本。菜单打开方式如下图:
Find Object by address
通过十六进制的地址查找对应的对象,见下图:
上面简单介绍了MAT工具的功能列表,下一篇文章将要通过实例详细进行分析。
精彩推荐 #
Spring Boot 快速入门系列(VI)—— 接口规范篇
Spring Boot 快速入门系列(V)—— 事务管理篇之 @Transactional
转发**'~'在看是真爱**
本文分享自微信公众号 - IT技术小咖(IT-arch)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。