3

我想在 JVM 崩溃时收集堆转储

所以我写了一个简单的代码

public class Test {
private String name;

public Test(String name) {
    this.name = name;
}

public void execute() {

    Map<String,String> randomData = new HashMap<String,String>();
    for(int i=0;i<1000000000;i++) {
       randomData.put("Key:" + i,"Value:" + i);
    }
}

public void addData() {
}

public static void main(String args[]) {
    String myName = "Aniket";
    Test tStart = new Test(myName);
    tStart.execute();
}
}

我运行它如下

[aniket@localhost Desktop]$ java -cp . -Xms2m -Xmx2m Test
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at Test.execute(Test.java:15)
    at Test.main(Test.java:25)

我得到了我想要的 OutOfMemoryError,但工作目录中没有堆转储(就像hs_err_pidXXXX.log我预期的那样)。我错过了什么?如何获得堆转储?

更新 :

我试了-XX:ErrorFile=.还是没用。如果上述方法不是获取堆转储(崩溃 JVM)的方法,我如何让我的 JVM 崩溃以获取这些日志?

4

6 回答 6

6

您正在混淆作为 JVM 崩溃引发的异常或错误。

由于 JVM 中的内部错误而发生 JVM 崩溃,您无法通过编写普通的 Java 程序来触发此错误(或者除非您发现错误,否则不应触发)

你正在做的是触发一个错误,这意味着程序继续运行,直到所有非守护线程退出。

检查堆的最简单工具是 JDK 附带的 VisualVM。如果要在 OutOfMemoryError 上触发堆转储,可以使用-XX:+HeapDumpOnOutOfMemoryError

于 2013-08-30T07:19:38.833 回答
1

当你看到下面

Exception in thread "main" java.lang.OutOfMemoryError

这意味着您的错误或异常由异常处理程序处理。这不是崩溃。

于 2013-08-30T07:38:09.040 回答
1

使用Jmap

jmap [options] pid

pid 是应用程序的进程id

于 2013-08-30T07:17:38.183 回答
0

Eclipse 有一个很棒的堆分析器

此外,您可以使用jps获取 PID,然后jmap获取堆本身。

如果您想使 JVM 崩溃,您最好的猜测是本机代码。

于 2013-08-30T07:18:12.393 回答
0

您可以将以下 JVM 参数传递给您的应用程序:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=

当您的应用程序遇到 OutOfMemoryError 时,此参数将自动触发指定“文件路径”中的堆转储。有 7 种不同的选项可以从您的应用程序中获取堆转储:

  1. 地图
  2. -XX:+HeapDumpOnOutOfMemoryError
  3. 指令
  4. 视觉虚拟机
  5. JMX
  6. 程序化方法
  7. 管理控制台

可以在本文中找到有关每个选项的详细信息。捕获堆转储后,您可以使用Eclipse 内存分析工具HeapHero等工具来分析捕获的堆转储。

于 2019-12-12T05:21:36.563 回答
0

查找要为其进行堆转储的进程 ID

ps -ef | grep java

通过运行上面的命令获得 PID 后,运行下面的命令以生成堆转储。

jmap -dump:format=b,file=<fileName> <java PID>
于 2018-04-18T17:22:44.810 回答