Java Heap Dump 分析步骤

前言

生产环境中Java应用难免遇到Out Of Memory或内存持续占用过大的问题。对于此类问题通用的分析方法是对问题进程的heap dump进行分析,重点关注占用内存较大的对象。本篇为大家带来分析Java进程heap dump的方法。

事先需要准备软下软件包:

  • JDK 11+(目前MAT最新版本1.13.0要求使用)
  • Memory Analyzer Tool (MAT)

MAT官方下载页面:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

软件包准备就绪后,解压JDK和MAT到任意目录,无需其他安装操作。

配置

由于目前新版本的MAT工具需要JDK11或者更高版本的运行环境,如果机器环境为JDK11以下,需要单独为MAT工具配置专门的JDK。方法为编辑MAT安装目录中的MemoryAnalyzer.ini文件,在文件开头加入如下内容:

-vm
/path/to/jdk-11.0.17+8/bin/java

/path/to/jdk-11.0.17+8/bin/java替换为真实环境中JDK11的java可执行文件的路径。

Heap Dump文件生成

这一节介绍下如何获取Java进程的heap dump。

使用命令

使用命令可以立刻获取某个Java进程的heap dump。

使用jmap命令:

jmap -dump:live,format=b,file=/path/to/heapdump.hprof 

使用jcmd命令:

jcmd  GC.heap_dump /path/to/heapdump.hprof

其中为需要分析的Java进程的pid。/path/to/heapdump.hprof为生成的heap dump文件所在的路径。

在特定时间点生成

考虑到如下场景:我们需要获取Java程序出现异常的时候(例如OOM)的heap dump。这种场景下我们无法使用上面讲解的命令,Java进程出现问题的时候可能已经被系统kill掉。因此我们需要配置JVM,让他能够在特定时间点自动生成heap dump。

下面列出生成heap dump的时间点和对应的JVM参数。

在OOM的时候生成heap dump:

-XX:+HeapDumpOnOutOfMemoryError

在full GC前生成heap dump:

-XX:+HeapDumpBeforeFullGC

在full GC后生成heap dump:

-XX:+HeapDumpAfterFullGC

在按下ctrl+break的时候生成heap dump:

-XX:+HeapDumpOnCtrlBreak

注意:指定heap dump文件生成的路径需要配置-XX:HeapDumpPath=/path/to/heapdump.hprof

使用VisualVM生成heap dump

生产环境多用命令或者JVM参数的方式生成heap dump。当然在本机开发测试的时候还可以使用图形化工具生成heap dump,例如VisualVM等。

VisualVM的下载页面:VisualVM: Download。下载后解压到任意目录,运行bin目录下的visualvm可执行文件,打开它的图形界面。

生成heap dump只需要在左边的application选择需要heap dump的进程,然后在右边栏目依次点击Monitor -> Heap Dump。如下图:

VisualVM

注意:如果运行VisualVM的时候提示JDK找不到,需要为VisualVM单独配置。方法为编辑VisualVM安装目录中的etc/visualvm.conf。修改或添加这一行:

visualvm_jdkhome="/path/to/java_home"

然后重新运行VisualVM。

Heap Dump分析

对于不是很大的heap dump文件(不大于MAT分析机器内存的1.2倍),我们可以将heap dump文件压缩后下载到本地,使用MAT图形界面方式分析。操作方法比较直观(File -> Open Heap Dump...),这里不再赘述。

生产环境中可能遇到特别大的heap dump。比如我们要分析一个30G的heap dump。将其在服务器上压缩之后,空间占用仍有大约10G,下载到本地耗时很长。本地开发机器一般也很少见32G内存机器,分析的时候会出现内存溢出问题。这种情况下我们需要使用MAT提供的命令行功能,在服务器上进行分析并输出分析报告。这些分析报告是静态的web页面,只有几百KB大小。需要在本地做的仅仅是将这些报告下载下来用浏览器打开,这样完美避免了本地开发环境配置不足的问题。

在服务器上使用MAT命令行分析的方法很简单。在MAT安装目录中执行:

./ParseHeapDump.sh xxx.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

其中xxx.hprof在实际使用的时候需要替换为hprof文件的路径。运行完毕后在hprof文件所在目录会生成一系列的index/threads文件和3个压缩文件。这3个压缩文件是我们重点关注的分析报告,分别为:

  • xxx_Leak_Suspects.zip:报告包含怀疑造成内存泄漏的地方,报告中包含了class层级图。对于OOM的场景能够很容易的定位到是哪个对象占用了大量内存不释放。
  • xxx_System_Overview.zip:包含heap dump基本信息,dump进程JVM的相关配置和线程信息等。
  • xxx_Top_Components.zip:查看占用空间最大的几个object/class/classloader/package等。报告以饼图和表格的形式展示。通过这个报告可以定位出Java程序运行时哪些对象占用内存较多,对问题排查和程序优化很有帮助。

这三个报告是分析问题的关键。我们通过报告找出内存占用过大的对象,然后结合日志和项目源代码分析程序逻辑,逐步定位出问题。

你可能感兴趣的:(Java Heap Dump 分析步骤)