当前位置: 首页 > 知识库问答 >
问题:

如何从核心转储文件中提取JVM堆转储?

凌志学
2023-03-14

我正在尝试将Java进程的Linux核心转储转换为堆转储文件,适合用Eclipse MAT进行分析。根据这篇博客文章,适应于较新的OpenJDK 12,我创建了一个核心转储,然后运行jhsdb jmap将转储转换为HPROF格式:

>sudo gcore -o dump 24934
[New LWP 24971]
...
[New LWP 17921]
warning: Could not load shared library symbols for /tmp/jffi4106753050390578111.so.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f94c7e9e98d in pthread_join (threadid=140276994615040, thread_return=0x7ffc716d47a8) at pthread_join.c:90
90      pthread_join.c: No such file or directory.
warning: target file /proc/24934/cmdline contained unexpected null characters
warning: Memory read failed for corefile section, 1048576 bytes at 0x7f93756a6000.
warning: Memory read failed for corefile section, 1048576 bytes at 0x7f9379bec000.
...
warning: Memory read failed for corefile section, 1048576 bytes at 0x7f94c82dd000.
Saved corefile dump.24934

> ls -sh dump.24934 
22G dump.24934

> /usr/lib/jvm/zulu-12-amd64/bin/jhsdb jmap --exe /usr/lib/jvm/zulu-12-amd64/bin/java --core dump.24934 --binaryheap --dumpfile jmap-dump.24934
Attaching to core dump.24934 from executable /usr/lib/jvm/zulu-12-amd64/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 12.0.1+12
null

> ls -sh jmap-dump.24934 
3.3M jmap-dump.24934

核心转储文件是22GB,而堆转储文件只有3MB,因此jhsdb jmap命令可能无法处理整个核心转储。此外,Eclipse MAT无法打开堆转储文件,并显示以下消息:HPROF解析器遇到违反HPROF规范的情况,无法安全处理。这可能是由于文件截断或JVM中的错误造成的


共有1个答案

邢炯
2023-03-14

亚历克斯,

这有两种可能。

首先,gcore是gdb的便捷脚本。我看到它会提示一些警告消息,说加载solib有困难。gdb可能会首先生成一个坏的核心文件。您可以尝试使用gdb加载核心文件,看看它是否可以解析它。

其次,jhsdb自己解析核心文件。可以使用环境变量LIBSAPROC_DEBUG=1获取其跟踪。它将帮助您了解解析中的错误。

为什么不直接使用jmap转储java堆呢?这将跳过coredump文件。

 类似资料:
  • 我正在分析几个堆转储,并对从堆转储获取jvm参数的方法感兴趣。使用eclipse memory analyzer我可以很容易地获得系统属性和类路径,但我想知道是否有方法获得其他参数,如-xms-xmx等。

  • 问题内容: 无论如何,当JVM崩溃时,是否有生成内核/堆转储文件的信息?由于这些文件通常对于查找代码中的错误非常有帮助。 问题答案: 使用以下JVM选项: JVM会将堆的内容转储到指定目录中的文件中。请注意,这仅在引发时发生,因为如果JVM因其他原因而崩溃,则确实不需要转储。 编辑:“布尔选项用-XX:+打开,而用-XX:-关闭。” docs

  • 问题内容: 我需要一种 从应用程序内部 请求堆转储 的方法 。 基本原理:当遇到特定的错误情况时,我想转储堆,以便可以看到内存中有什么内容。 但是我想使它自动化(例如,当我检测到某些特定情况发生时。或者当看门狗不再收到ping命令时;当某些测试失败时)。因此,我需要一种从应用程序本身内部转储堆的方法。我似乎无法通过MX bean的东西找到它。尽管MX Bean可以通过监视器和“可拥有的同步器”信息

  • 问题内容: 每次我的应用程序崩溃时,都不会生成核心转储文件。我记得几天前,它 是 在另一台服务器 上 生成的。我正在使用bash屏幕运行应用程序,如下所示: 如您所见,如果要生成核心转储,则在使用哪个选项很重要,但是当遇到分段错误时,它仍然不会生成。我该如何运作? 问题答案: 确保当前目录(崩溃时可能会更改目录)是可写的。如果服务器调用,则该目录必须是该用户可写的。 同时检查。这可能会将核心转储重

  • 问题内容: 运行C程序时,它显示 “((核心转储)”), 但是在当前路径下看不到任何文件。 我已经设置并验证了: 我也试图找到一个名为“ core”的文件,但是没有得到core dumped文件? 任何帮助,我的核心文件在哪里? 问题答案: 阅读/usr/src/linux/Documentation/sysctl/kernel.txt。 [/ proc / sys / kernel /] cor

  • 问题内容: 每当进程崩溃时,我都想创建一个核心转储。目前,我正在采用这种方法: 使用gcc / g ++的“ -g”构建程序的特殊“调试”版本。 执行“ ulimit -c unlimited” 现在,只要程序崩溃,我们就获得核心转储。 但我想减少步骤数,以便: 应始终创建核心转储。即使是“发布”版本。不应要求用户手动执行命令“ ”。 该核心转储的回溯应该能够给出调用的文件,函数,行号。那是人类可