乐趣区

关于java:性能监控之常见-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 并在新选项卡中将其关上:


JVisualVM
留神:咱们能够在“根本信息”局部中找到创立的文件的门路。从 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/heapd…

六、论断

在本文中,咱们展现了用 Java 捕捉 Heap Dump 办法 的多种办法。

常见的 dump 形式

从教训上来说,咱们应该记得在运行 Java 应用程序时始终应用 HeapDumpOnOutOfMemoryError 参数。

退出移动版