性能监控之常见 Java Heap Dump 方法
一、前言
在本文中,我们总结下抓 Java dump 的几种不同方法。
Java Heap Dump 是特定时刻 JVM 内存中所有对象的快照。它们对于解决内存泄漏问题和分析 Java 应用程序中的内存使用情况非常有用。
Java Heap Dump 通常以二进制格式的 hprof 文件存储。我们可以使用 jhat 或 JVisualVM 之类的工具打开和分析这些文件。同样,使用 MAT 工具分析是很常见的。
二、JDK 工具包
JDK 附带了几个以不同方式 Heap Dump 的工具。所有这些工具都位于 JDK 主目录下的 bin 文件夹下。因此,只要这个目录包含在系统路径中,我们就可以直接从命令行启动它们。
1、jmap
jmap 是一种工具,用于打印有关正在运行的 JVM 中的内存的统计信息。我们可以将其用于本地或远端进程。
要使用 Jmap Heap Dump ,我们需要使用 Heap Dump 参数:
jmap -dump:[live],format=b,file=<file-path> <pid>
与该参数一起,我们应该指定几个参数:
- live:如果设置,则仅打印具有活动引用的对象,并丢弃准备好进行垃圾回收的对象。此参数是可选的。
format = b:指定转储文件将采用二进制格式。如果未设置,结果是相同的- file:将写入的文件
- pid:Java 进程的 ID
举一个例子是这样的:
jmap -dump:live,format=b,file=/tmp/dump.hprof 12587
注意:我们可以使用 jps 命令轻松获取 Java 进程的pid。jmap 是作为实验工具在 JDK 中引入的。因此,在某些不支持的情况下,最好使用其他工具代替。
2、jcmd
jcmd 是一个非常完整的工具,可以通过向 JVM 发送命令请求来工作。我们必须在运行 Java 进程的同一台机器上使用它。
它的最多命令就是 GC.heap_dump,我们可以通过指定进程的 pid 和输出文件路径来使用它来 Heap Dump:
jcmd <pid> GC.heap_dump <file-path>
我们可以使用上面例子中使用的相同参数执行它:
jcmd 12587 GC.heap_dump /tmp/dump.hprof
与 jmap 一样,生成的 dump 为二进制格式。
3、JVisualVM
JVisualVM 是带有图形用户界面的工具,它使我们可以监控 Java 应用程序,对其进行故障排除和分析。GUI 简单,直观并且易于使用。
我们可以右键单击 Java 进程并选择“线程dump”选项,该工具将创建 dump 并在新选项卡中将其打开:

注意:我们可以在“基本信息” 部分中找到创建的文件的路径。从 JDK 9开始,Visual VM 不包括在 Oracle JDK 和 Open JDK 发行版中。因此,如果我们使用的是 Java 9 或更高版本,则可以从 Visual VM 开源项目站点获得 JVisualVM 。地址:https://visualvm.github.io/
三、自动抓取 heap dump
上面介绍所有工具均在特定时间手动去 dump 的。在某些情况下,我们希望在发生 java.lang.OutOfMemoryError 时获取 Heap Dump ,以帮助我们分析问题。
对于这种情况,Java 提供了 HeapDumpOnOutOfMemoryError 命令行参数,当抛出 java.lang.OutOfMemoryError 时,程序会生成 heap dump :
java -XX:+HeapDumpOnOutOfMemoryError
默认情况下,它将 dump 存储在我们正在运行应用程序的目录中的 java_pid <pid> .hprof文件中。如果要指定另一个文件或目录,可以在 HeapDumpPath 参数中进行设置:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>
使用此参数,当我们的应用程序内存不足时,我们将能够在日志中看到包含 dump 的已创建文件:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Dumping heap to java_pid12587.hprof ...
Exception in thread "main" Heap dump file created [4744371 bytes in 0.029 secs]
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at com.baeldung.heapdump.App.main(App.java:7)
在上面的示例中,它已写入到 java_pid12587.hprof 文件中。
就像我们看到的,此参数非常有用,使用此参数运行应用程序时没有任何开销。因此,强烈建议始终使用此参数,尤其是在生产中。
最后,还可以在运行时通过使用 HotSpotDiagnostic MBean 来指定此参数。为此,我们可以使用 JConsole 工具并将HeapDumpOnOutOfMemoryError VM 参数值设置为 true:

四、JMX
我们将使用在上一节中简要介绍的 HotSpotDiagnostic MBean。该 MBean 提供了一个 dumpHeap 方法,该方法接受 2 个参数:
- outputFile:dump 文件的路径。该文件应具有 hprof 扩展名
- live:如果设置为 true,则它仅 dump 内存中的活动对象,就像我们之前在 jmap上看到的那样
下面我们将介绍两种不同的方法来调用此方法来 heap dump。
1、JConsole
使用 HotSpotDiagnostic MBean 的最简单方法是使用 JMX 客户端(例如JConsole)
打开 JConsole 并连接到正在运行的 Java 进程,则可以导航到 MBeans 选项卡并在 com.sun.management下找到HotSpotDiagnostic。在操作中,我们可以找到我们之前描述的 dumpHeap 方法:
如所示,为了执行 dumpHeap 操作,我们只需要引入参数 outputFile 并将其存在于 p0 和 p1 文本字段中。
2、编程
使用 HotSpotDiagnostic MBean 的另一种方法是通过从 Java 编程方式调用它。
为此,我们首先需要获取一个 MBeanServer 实例,以便获取在应用程序中注册的 MBean。之后,我们只需要获取 HotSpotDiagnosticMXBean 的实例 并调用其 dumpHeap 方法。
import javax.management.MBeanServer;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Paths;
public class HeapDump {
public static void dumpHeap(String filePath, boolean live) throws IOException {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
mxBean.dumpHeap(filePath, live);
}
public static void main(String[] args) throws IOException {
String file = Paths.get("dump.hprof").toFile().getPath();
dumpHeap(file, true);
}
}
注意,不能覆盖 hprof 文件。因此,在创建打印 heap dumps 的应用程序时应该考虑到这一点。如果我们没有这样做,就会得到一个异常:
Exception in thread "main" java.io.IOException: File exists
at sun.management.HotSpotDiagnostic.dumpHeap0(Native Method)
at sun.management.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:60)
五、Arthas
Arthas 是阿里提供的一款 Java 开源诊断工具。能够查看应用的线程状态、JVM 信息等;并能够在线对业务问题诊断,比如查看方法调用的出入参数、执行过程、抛出的异常、输出方法执行耗时等,大大提升了线上问题的排查效率。
Arthas 提供 heapdump 命令:dump java heap, 类似 jmap命令的 heap dump功能。
dump 到指定文件:
[arthas@58205]$ heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof...
Heap dump file created
只 dump live对象:
[arthas@58205]$ heapdump --live /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof...
Heap dump file created
dump 到临时文件:
[arthas@58205]$ heapdump
Dumping heap to /var/folders/my/wy7c9w9j5732xbkcyt1mb4g40000gp/T/heapdump2019-09-03-16-385121018449645518991.hprof...
Heap dump file created
更多参考:https://arthas.gitee.io/heapdump.html
六、结论
在本文中,我们展示了用 Java 捕获 Heap Dump 方法 的多种方法。
常见的dump方式
从经验上来说,我们应该记得在运行 Java 应用程序时始终使用 HeapDumpOnOutOfMemoryError 参数。
性能监控之常见 Java Heap Dump 方法的更多相关文章
- Java heap dump触发和分析(转)
为了分析java应用的内存泄漏,使用thread dump往往解决不了问题.使用jstat[eg:jstat-gcutil pid 1000 5]工具查看运行的java应用的heap size,per ...
- 使用VisualVM查看Java Heap Dump
浏览Heap Dump 可以使用VisualVM浏览heap dump文件的内容,从而快速查看在堆中分配的对象.Heap dumps在主窗口的heap dump子标签页中显示.你可以打开保存在本地的h ...
- Java Heap dump文件分析工具jhat简介
jhat 是Java堆分析工具(Java heap Analyzes Tool). 在JDK6u7之后成为标配. 使用该命令需要有一定的Java开发经验,官方不对此工具提供技术支持和客户服务. 用法: ...
- 通过分析java heap dump解决生产问题
最近在生产环境遇到一个问题,正常情况下,ECS CPU始终保持在10%以下,内存也只占用40%左右,但是连续2天出现了CPU占用100%的情况,然后系统卡住.看阿里云的ECS监控,能看到CPU飙到了1 ...
- 分析 Java heap dump工具之IBM HeapAnalyzer
IBM HeapAnalyzer是一款免费的JVM内存堆的图形分析工具,它可以有效的列举堆的内存使用状况,帮助分析Java内存泄漏的原因. 功能与MAT类似. 1.下载 https://www.ibm ...
- java-JProfiler(三)-进行本地JVM的性能监控-监视本地java程序
1.打开JProfiler 默认会启动快速窗口[或者使用菜单Session→Start Center]打开 这里监视本地java程序,故在 主界面 2.查看监视界面 这时就可以查看 Instance ...
- Java Heap Dump On OutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError Batch "C:\Program Files\Java\jdk1.8.0_162\bin\java.exe" -X ...
- Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
原文地址:http://www.javatang.com JVM Heap Dump(堆转储文件)的生成 正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了J ...
- java程序性能分析之thread dump和heap dump
一.dump基本概念 在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题.这些文件记录了JVM运行期间的内存占用.线程执行等情况,这就是我们常说的 ...
随机推荐
- Windows核心编程 第九章 线程与内核对象的同步(下)
9.4 等待定时器内核对象 等待定时器是在某个时间或按规定的间隔时间发出自己的信号通知的内核对象.它们通常用来在某个时间执行某个操作. 若要创建等待定时器,只需要调用C r e a t e Wa i ...
- tp5.1中返回当天、昨天、当月等的开始和结束时间戳
/** * 返回今日开始和结束的时间戳 * * @return array */function today(){ list($y, $m, $d) = explode('-', date('Y-m- ...
- vuex、localStorage、sessionStorage之间的区别
vuex存储在内存中,localStorage以文件形式存储在本地,sessionStorage针对一个session(阶段)进行数据存储. 当页面刷新时vuex存储的数据会被清除,localStor ...
- Day015 Error和Exception
Error和Exception 什么是异常 实际工作中,遇到的情况不可能是非常完美的.比如:你写的某个模块,用户输入不一定符合你的要求.你的程序要打开某个文件,这个文件可能不存在或者文件的格式不对,你 ...
- Kafka万亿级消息实战
一.Kafka应用 本文主要总结当Kafka集群流量达到 万亿级记录/天或者十万亿级记录/天 甚至更高后,我们需要具备哪些能力才能保障集群高可用.高可靠.高性能.高吞吐.安全的运行. 这里总结内容主 ...
- [知识路书]beta设计和计划
[知识路书]beta设计和计划 一.需求再分析 根据用户反馈,是否发现之前的需求分析有偏差?为什么会出现这种偏差?beta阶段你们是否能真的分析清楚用户需求?如何做到? 根据alpha阶段的推广情况以 ...
- Flink使用二次聚合实现TopN计算
一.背景说明: 有需求需要对数据进行统计,要求每隔5分钟输出最近1小时内点击量最多的前N个商品,数据格式预览如下: 543462,1715,1464116,pv,1511658000 662867,2 ...
- Tomcat的使用和配置
Tomcat的使用 安装 在tomcat官网找到你需要用的 Tomcat 版本对应的 zip 压缩包,解压到需要安装的目录即可 目录介绍 bin : 专门用来存放Tomcat服务器的可执行文件 con ...
- 联想RD350板载RAID110i,安装CentOS 7 不识别RAID设备
联想RD350板载RAID110i,安装CentOS 7 不识别RAID设备 情况如题所述. 1. 确认BIOS中 Boot mode为[UEFI]或者[AUTO] 2. 确认BIOS中 Stor ...
- SystemVerilog 编写FSM
SystemVerilog 编写FSM 题目 SystemVerilog实现 仿真 SystemVerilog 编写FSM 好书: https://github.com/yllinux/blogPic ...