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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39545359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:27:14  来源:igfitidea点击:

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

javamemory-leaksout-of-memoryheap-dump

提问by Anjan Baradwaj

In recent times, I have encountered java.lang.OutOfMemoryErrorexception while running an application.

最近,我java.lang.OutOfMemoryError在运行应用程序时遇到异常。

During one such instance, I was able to get the heap dump using jvisualvm.

在一个这样的实例中,我能够使用jvisualvm.

I am able to open the .hprofheap dump file obtained from the heap dump using NetBeans 8.1IDE but I am not aware of how to analyze the data dump. I'd like to know how to read the dump file and take corrective actions to reduce the out of memory exception from an application perspective.

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

回答by Nicolas Filotto

There are many ways to find the root cause of a memory leak, like using a profiler such as JProfilerand simply applying what is described in this great video. You could also have a look to Eclipse Memory Analyzeralso know as MATthat 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 Reporthere). Another way could be to use Java Flight Recorderby applying this approach. Or using JVisualVMusing the approach described in this video.

有很多方法可以找到内存泄漏的根本原因,例如使用分析器(例如JProfiler)并简单地应用此精彩视频中描述的内容。您还可以查看Eclipse 内存分析器,也称为MAT,它将能够分析您的堆转储并提出内存泄漏的潜在原因,如您在此视频中看到的(您可以在此处找到有关可疑报告的更多信息) . 另一种方法是通过应用这种方法来使用Java Flight Recorder。或者使用本视频中描述的方法使用JVisualVM

回答by Gergely Bacso

The tool you need for this case is this app:

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

Memory Analyzer Tool

内存分析器工具

Just download & start, then load your hprof file. It may take a minute or two depending on the size of your hprof, but then you will be presented with a nice analysis on your memory usage. It is very easy to use, and automatically highlights the potential memory leaks, performs analysis on the data from different angles.

只需下载并启动,然后加载您的 hprof 文件。这可能需要一两分钟,具体取决于您的 hprof 的大小,但随后您将看到有关内存使用情况的很好的分析。它非常易于使用,并自动突出显示潜在的内存泄漏,从不同角度对数据进行分析。

I am using MAT exclusively when I am dealing with non-trivial memory issues, and I solved all of these issues as far as I remember.

当我处理重要的内存问题时,我只使用 MAT,并且据我所知,我解决了所有这些问题。

回答by Tim Cooper

Most of the time all you need to know is which are the classes most at fault of chewing up memory. You can use: jmap -histo against a running process, which is handy if it's a large JVM...you don't want to be fiddling around with large heap-dump files. It must be run as the same Linux user that owns the process, so e.g. in Linux you can use:

大多数情况下,您只需要知道哪些类最容易占用内存。您可以使用: jmap -histo 针对正在运行的进程,如果它是一个大型 JVM,这很方便……您不想摆弄大型堆转储文件。它必须以拥有该进程的同一 Linux 用户身份运行,因此例如在 Linux 中,您可以使用:

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

Obviously "histo" is short for "histogram". This will dump a histogram to stdout, so you probably want to pipe it to a file for analysis. It'll be sorted by the number of instances * size of instance, so look at the top 10 entries and you might have your answer.

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

回答by rogerdpack

In general, basically what you do is analyze "what is using the most RAM"? then when you've figured that out (and "is it probably the problem of me running out of RAM?") then you try and figure out why there are so many of those objects around. Are they being referenced by something that is holding onto objects but needn't? Or that is accidentally holding onto references of thigns it shouldn't? Are you using too large of archicture/paradigm (ex: storing "everything in one big array")? Is your database client "buffering" large ResultSets into RAM before returning them? Etc...

一般来说,基本上你所做的是分析“什么是使用最多的 RAM”?然后当你弄清楚了(“这可能是我用完了 RAM 的问题吗?”)然后你试着弄清楚为什么有这么多这样的对象。它们是否被持有对象但不需要的东西引用?或者那是不小心保留了它不应该的东西的引用?您是否使用了过多的架构/范式(例如:将“所有内容都存储在一个大数组中”)?在返回它们之前,您的数据库客户端是否将大型 ResultSets“缓冲”到 RAM 中?等等...