如何分析.hprof文件?

270

我有一台生产服务器,运行以下标记:-XX:+HeapDumpOnOutOfMemoryError

昨晚当我们的服务器遇到堆错误时,它生成了一个名为java-38942.hprof的文件。原来该系统的开发人员知道这个标记,但不知道如何从中获得任何有用信息。

有什么想法吗?

8个回答

248
如果你想使用相当先进的工具来进行一些严肃的探索,请看看Eclipse的Memory Analyzer项目,该项目由SAP贡献。

你可以做的一些事情非常惊人,比如找到内存泄漏等 -- 包括对内存中的对象运行一种类型的限制SQL(OQL),即

SELECT toString(firstName) FROM com.yourcompany.somepackage.User

绝对是一个杰出的工具.


20
我想为Eclipse Memory Analyzer打个+100分。我现在正在尝试筛选一个400MB以上的堆转储文件,而jhat花了70多分钟才读取完这个文件,然后导致整个JVM崩溃。而EMA能在不到5分钟内打开它。 - matt b
4
我在使用Eclipse Memory Analyzer打开HPROF文件时,一直遇到解析错误(这些文件实际上也是由Eclipse转储的!)。很不幸,叹气。 - lost_bits1110
4
MAT仍然可能需要相当大量的RAM(比JHAT少但仍然很多)。如果发生这种情况,请参考https://dev59.com/12w05IYBdhLWcg3wahJM中的提示。 - rogerdpack
1
Error opening heap dump 'strictmode-death-penalty.hprof'. Check the error log for further details. Error opening heap dump 'strictmode-death-penalty.hprof'. Check the error log for further details. Unknown HPROF Version (JAVA PROFILE 1.0.3) (java.io.IOException) Unknown HPROF Version (JAVA PROFILE 1.0.3) - Dr.jacky

88
你可以使用JHAT,它是JDK默认提供的Java堆分析工具。 它是命令行的,但启动一个Web服务器/浏览器,您可以使用它来检查内存。 它不是最用户友好的工具,但至少它已经安装在大多数地方。 一个非常有用的视图是底部的“堆直方图”链接。
例如:jhat -port 7401 -J-Xmx4G dump.hprof jhat现在也可以执行OQL(底部链接“执行OQL”)。

5
执行上述命令后,在控制台中会出现"server is ready"和端口号7401的信息。然后打开URL:http://localhost:7401,可以在浏览器窗口中查看详细信息。 - Gautam
1
java.io.IOException: Version string not recognized at byte 17 - Dr.jacky
1
最新版本的OpenJDK或Oracle JDK默认情况下未提供此功能。 - em_bo

39

您还可以使用Netbeans Profiler的HeapWalkerVisual VM独立工具。与JHAT相比,Visual VM是一个很好的替代品,因为它是独立的,并且比JHAT更易于使用。

您需要Java 6+才能充分使用Visual VM。


你应该添加一条注释,说明这仅适用于Java 6和7。 - Nick Stinemates
据我所知,HeapWalker和VisualVM不需要Java 6/7来读取HPROF文件。 - James Schek
我刚试着用Java 5加载它,但提示说“请使用Java 6或7”。我做错了什么? - Nick Stinemates
嗯,也许你需要运行Java 6,但可以读取Java 5 HPROF文件(也许这就是我让它工作的方式)。我知道你无法从运行Java 5的应用程序上使用Visual VM创建堆转储。稍后更新。 - James Schek
你也可以使用Java SDK中的可视化JVM,只需在JAVASDK/bin文件夹中查找jvisualvm.exe即可。 - xxxvodnikxxx

15
我个人更喜欢使用VisualVM。我喜欢VisualVM中的一个功能,即堆转储比较。当您进行堆转储分析时,有各种方法可以找出导致崩溃的原因。其中一种我发现有用的方法是比较正常状态和异常状态下的堆转储。
以下是您可以遵循的步骤: 1. 获取OutOfMemoryError的堆转储,我们称之为“oome.hprof”。您可以通过JVM参数HeapDumpOnOutOfMemoryError获取此参数。 2. 重新启动应用程序,让它运行一段时间(几分钟/几小时,具体取决于您的应用程序)。在应用程序仍在运行时获得另一个堆转储。我们将其称为“healthy.hprof”。 3. 您可以在VisualVM中打开这两个转储,并进行堆转储比较。您可以按类或包级别进行比较。这通常可以指向问题方向。
链接:https://visualvm.github.io

15

请获取Eclipse内存分析器。这是目前最好的免费工具。

JHAT只适用于"玩具应用程序"。


3
JHAT是让那些用LILO自己构建BSD发行版的“l33t”黑客印象深刻的必备工具。等等...他们无论如何都不会使用Java。 :-) - James Schek
我认为这更像是一条评论... :\ - rogerdpack
是的,JHAT适用于“玩具应用程序”。我有一个转储文件(9GB),使用20GB堆运行JHAT大约需要30分钟,最终由于OOM而失败。Eclipse Memory Analyzer在1分钟内使用15GB堆处理它。 - zwy
1
当我打开一个3GB的转储文件时,Eclipse Memory Analyzer会显示内存不足错误并且无法打开转储文件。Windows 10 / JRE17
  • "解析来自'D:\ java_pid12269.hprof'的堆转储时发生内部错误。" java.lang.OutOfMemoryError
- mkag

11

YourKit Java Profiler 似乎也可以处理它们。


9
如果您想对堆转储进行自定义分析,则可以使用以下内容:

该库速度快,但您需要用Java编写自己的分析代码。

从文档中了解到:

  • 不会在磁盘上创建任何临时文件来处理堆转储
  • 可以直接处理GZ压缩堆转储
  • HeapPath符号表示法

链接已失效。 - Escay

0
我正在使用IntelliJ IDEA的Ultimate版本中的分析器。 在IDEA中,按两次Shift键。
操作选项卡中写入“分析器”。 选择带有图标的“分析器”行。 然后点击打开快照..按钮。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接