如何分析 .hprof 文件中的堆数据并使用它来减少内存泄漏?

How to analyze heap data from .hprof file and use it to reduce memory leaks?

最近,我在 运行 申请时遇到 java.lang.OutOfMemoryError 异常。

在一个这样的实例中,我能够使用 jvisualvm 获得堆转储。

我可以使用 NetBeans 8.1 IDE 打开从堆转储中获得的 .hprof 堆转储文件,但我不知道如何分析数据转储。我想知道如何读取转储文件并采取纠正措施以从应用程序的角度减少内存不足异常。

这个案例需要的工具是这个应用程序:

Memory Analyzer Tool

只需下载并启动,然后加载您的 hprof 文件。这可能需要一两分钟,具体取决于您的 hprof 的大小,但是随后您将看到一个关于您的内存使用情况的很好的分析。非常简单易用,自动高亮潜在内存泄漏,对数据进行多角度分析。

我在处理重要的内存问题时专门使用 MAT,据我所知,我解决了所有这些问题。

有很多方法可以找到内存泄漏的根本原因,例如使用分析器 JProfiler and simply applying what is described in this great video. You could also have a look to Eclipse Memory Analyzer also know as MAT that will be able to analyze your heap dump and propose potential causes of your memory leak as you can see in this video (you can find more information about the Suspect Report here). Another way could be to use Java Flight Recorder by applying this approach. Or using JVisualVM using the approach described in this video

总的来说,基本上你做的就是分析"what is using the most RAM"?然后当你想通了(和"is it probably the problem of me running out of RAM?")然后你试着弄清楚为什么周围有这么多这样的物体。它们是否被持有但不需要的对象引用?还是不小心保留了不应该引用的东西?您是否使用了太大的 archicture/paradigm(例如:存储 "everything in one big array")?您的数据库客户端 "buffering" 大 ResultSets 在返回之前是否进入 RAM?等等...

大多数时候,您需要知道的是哪些 类 最容易消耗内存。您可以使用:jmap -histo 针对 运行ning 进程,如果它是大型 JVM,这将很方便……您不想摆弄大型堆转储文件。它必须 运行 与拥有该进程的 Linux 用户相同,例如在 Linux 中,您可以使用:

sudo -u <user> jmap -histo <pid>

显然 "histo" 是 "histogram" 的缩写。这会将直方图转储到标准输出,因此您可能希望将其通过管道传输到文件进行分析。它将按实例数 * 实例大小排序,所以查看前 10 个条目,您可能会有答案。