首页 > 编程语言 >性能监控之常见 Java Heap Dump 方法

性能监控之常见 Java Heap Dump 方法

时间:2023-04-06 13:02:47浏览次数:38  
标签:Java Dump dump hprof heap Heap java


一、前言

在本文中,我们总结下抓 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 并在新选项卡中将其打开:

性能监控之常见 Java Heap Dump 方法_JavaJVisualVM

注意:我们可以在“基本信息” 部分中找到创建的文件的路径。从 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:性能监控之常见 Java Heap Dump 方法_Java_02

四、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 方法:性能监控之常见 Java Heap Dump 方法_Java_03

如所示,为了执行 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 方法 的多种方法。

性能监控之常见 Java Heap Dump 方法_Java_04常见的dump方式

从经验上来说,我们应该记得在运行 Java 应用程序时始终使用 HeapDumpOnOutOfMemoryError 参数。






标签:Java,Dump,dump,hprof,heap,Heap,java
From: https://blog.51cto.com/u_15181572/6172675

相关文章

  • 1- Java概述
    1.人机交互1.1什么是cmd?就是在windows操作系统中,利用命令行的方式去操作计算机。我们可以利用cmd命令去操作计算机,比如:打开文件,打开文件夹,创建文件夹等。1.2如何打开CMD窗口?按下快捷键:win+R。此时会出现运行窗口。在运行窗口中输出cmd输出回车。解......
  • 2-Java基础语法
    1.注释注释是对代码的解释和说明文字。Java中的注释分为三种:单行注释://这是单行注释文字多行注释:/_这是多行注释文字这是多行注释文字这是多行注释文字_/注意:多行注释不能嵌套使用。文档注释(暂时用不到):/*_这是多行注释文字这是多行注释文字这是多......
  • java面试题学习记录2
    1.索引的分类 主键索引,联合索引,唯一索引,全文索引,普通索引2.锁的分类 行锁:操作数据库时,锁定整行数据 表锁:操作数据库时,锁定整表数据 乐观锁:多线程情况下,认为其他线程不会去修改的数据,所以不会上锁,但是会在跟新时,判断一下数据有没有被改变,可以用版本号机制 悲......
  • 【过滤器设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
    简介过滤器模式(FilterPattern)或标准模式(CriteriaPattern),是一种结构型模式。这种模式允许使用不同的标准条件来过滤一组对象,并通过逻辑运算的方式把各条件连接起来,它结合多个标准来获得单一标准。例子将创建一个Person对象、Criteria接口和实现了该接口的实体类,来过滤Perso......
  • 走进Java接口测试之从0到1搭建数据驱动框架(需求篇)
    前言一个“好的”数据驱动框架,需要从“时间”、“人力”、“收益”这三个方面出发,做好“取舍”。不能由于被测业务系统发生一些变更,就导致花费了几个小时的脚本无法执行。同时,我们需要看到“收益”,不能为了总想看到100%的成功,而减少必须做的工作,这导致可能都需要进行大量的维护。......
  • org.apache.shiro.session.InvalidSessionException: java.lang.I
    1.遇到以下异常,找了好长时间,终于解决,报的异常如下:七月07,20173:02:16下午org.apache.catalina.core.StandardWrapperValveinvoke严重:Servlet.service()forservlet[SpringMVC]incontextwithpath[/IMP]threwexception[org.apache.shiro.session.InvalidSessionEx......
  • java中如何创建带路径的文件
    请教各位大侠了,java中如何创建带路径的文件,说明下这个路径不存在------回答---------------其他回答(2分)---------JavacodeFilef=newFile("c:/1.txt");if(!f.exists()){try{f.createNewFile();}catch(IOExceptione){e.printStackTrace();}}------其他回答(18分)----......
  • java之常用正则表达式
    http://wenku.baidu.com/link?url=gLcsovVfQqRTVayxGGaWBpjyewi4qOopgEJ3JYWaPSm_VqIsX1ALI_ZJpnrMf51P2eFpWK03DbPQly7Hfs4yI1hqWJnHDSJBjfzKkrfLZKWhttps://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx......
  • java 生成不重复的随机数
    importjava.text.SimpleDateFormat;importjava.util.Date;publicclassTest2{ publicstaticvoidmain(String[]args){ SimpleDateFormatformatter2=newSimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); SimpleDateFormatformatter=newSimpleDateF......
  • java中的NAN和INFINITY
      java中的NAN和INFINITY java浮点数运算中有两个特殊的情况:NAN、INFINITY。1、INFINITY:在浮点数运算时,有时我们会遇到除数为0的情况,那java是如何解决的呢?我们知道,在整型运算中,除数是不能为0的,否则直接运行异常。但是在浮点数运算中,引入了无限这个概念,我们来看一下Double和Float......