最近,我在运行应用程序时遇到java.lang.OutOfMemoryError
异常。
在一个这样的实例中,我能够使用jvisualvm
获取堆转储。
我可以使用.hprof
IDE打开从堆转储获取的NetBeans 8.1
堆转储文件,但我不知道如何分析数据转储。我想知道如何读取转储文件并采取纠正措施以从应用程序的角度减少内存不足异常。
答案 0 :(得分:10)
有许多方法可以找到内存泄漏的根本原因,例如使用JProfiler等分析器并简单地应用this great video中描述的内容。您还可以查看 Eclipse Memory Analyzer ,也称为MAT,它将能够分析您的堆转储并提出内存泄漏的潜在原因,如您在{{3 (您可以找到有关可疑报告 this video)的更多信息。另一种方法是通过应用here来使用 Java Flight Recorder 。或者使用 JVisualVM ,使用this approach中描述的方法。
答案 1 :(得分:1)
此案例所需的工具是这个应用程序:
只需下载&启动,然后加载您的hprof文件。可能需要一两分钟,具体取决于您的hprof的大小,但随后您将获得有关内存使用情况的精彩分析。它非常易于使用,并自动突出显示潜在的内存泄漏,从不同角度对数据进行分析。
当我处理非平凡的记忆问题时,我只使用MAT,而且就我记忆而言,我解决了所有这些问题。
答案 2 :(得分:1)
大多数时候,您需要知道的是哪类最容易消耗内存。您可以使用:jmap -histo针对正在运行的进程,如果它是大型JVM,则非常方便...您不想摆弄大型堆转储文件。它必须以拥有该进程的Linux用户身份运行,例如在Linux中,您可以使用:
sudo -u <user> jmap -histo <pid>
显然“ histo”是“ histogram”的缩写。这会将直方图转储到stdout,因此您可能希望将其通过管道传输到文件中进行分析。它将按照实例数*实例大小进行排序,因此请查看前10个条目,您可能会得到答案。
答案 3 :(得分:0)
总的来说,基本上你所做的就是分析“什么是使用最多RAM”?那么当你想出来的时候(以及“这可能是我的RAM耗尽的问题吗?”)然后你试着弄清楚为什么周围有这么多的物体。它们是被引入物体而不需要物体引用的吗?或者那是不小心抓住了它们不应该引用的东西?您是否使用过大的架构/范例(例如:将所有内容存储在一个大阵列中)?在返回之前,您的数据库客户端是否将大型ResultSet“缓冲”到RAM中?等...