比较 Java 内存堆转储:Java 桌面应用程序的内存分析 [关闭]

Posted

技术标签:

【中文标题】比较 Java 内存堆转储:Java 桌面应用程序的内存分析 [关闭]【英文标题】:Comparing java memory heap dumps: Memory profiling for Java desktop application [closed] 【发布时间】:2009-11-21 01:52:38 【问题描述】:

这是一个更具体的问题,可以在 another question that I have asked recently 上跟进。这个问题的正确答案也将获得上一个问题的正确答案(因为它仍然处于不确定状态)!

基本上,我有一个存在内存泄漏问题的 Java 桌面应用程序。我正在使用 Netbeans IDE 中的内存分析器来分析内存问题。这些是我到目前为止所采取的步骤:

    将新的内存分析器附加到 Netbeans 项目 在几行精心挑选的代码中定义分析点,并将它们设置为触发内存堆转储 在分析模式下运行应用程序

这样做的最终结果是我在*.hprof 文件中保存了几个内存转储到磁盘。 Netbeans IDE 让我可以细读这些内存转储的内容(基本排序和搜索),甚至让我遍历堆,通过查看每个实例中包含的引用,以及哪些其他对象引用每个实例.这一切都很好,到目前为止,我已经能够识别出 1 或 2 个相当明显的内存泄漏并纠正了大约 15% 的问题。

但是,现在我使用的方法依赖于在特定时间创建关于哪些对象不应在内存中的假设,然后对其进行调查。我现在追求的是比较两个单独的堆转储的方法:基本上我有两个应该几乎相同的堆转储,因为应用程序已恢复到相同的状态。

但是,一个是在内存泄漏之前,另一个是在内存泄漏之后,所以它们显然是不同的。如果我能够使用 of 工具比较这两个堆,而不是像现在这样手动比较,那么我不需要依靠假设来确定泄漏发生的位置,并且可以只使用工具为我识别它们。 这对我来说很重要,因为此特定应用程序涉及大量的类和实例(分别为 700 多个和数百万个)

Netbeans IDE 的分析器是否能够做到这一点? 如果没有,是否有能够执行此任务的工具?

谢谢!

【问题讨论】:

【参考方案1】:

还有一个用于此任务的免费 GUI 工具:VisualVM。它允许您获取多个堆转储,然后告诉它与另一个进行比较,将不同的内容显示为列表,并以每个元素的已用内存份额的图形表示。此外,以交互方式浏览堆转储差异比使用 jhat 更舒适

【讨论】:

如果对我的回答投反对票的人向我解释她/他为什么这样做,那就太好了。谢谢。 我使用 VisualVM 进行了几次堆转储;现在我该如何比较它们? 仍然没有回答,在 UI 中肯定不明显。 找到了。在右上角的摘要选项卡中,有一个“比较两个堆转储”链接。馅料少,味道好。 它已被移至堆转储屏幕内“类”的右上角。【参考方案2】:

您可以使用jhat。具体查看我引用的页面上的选项(-baseline baseline-dump-file),它说以下内容:

“指定基线堆转储。两个堆转储中具有相同对象 ID 的对象将被标记为非“新”。其他对象将被标记为“新”。这在比较两个不同的堆转储时很有用。 "

这在比较两个堆转储时可能会有所帮助。

【讨论】:

这要求两个堆转储都来自应用程序的同一运行(这似乎不是 bguiz 的问题)。 @broschb,+1,谢谢 - 这对我有用!我对 JHAT 的唯一问题是它的界面是通过一个相当静态的网页,不是很用户友好。话虽这么说,能够使用References to this object 遍历堆转储,并且能够使用New Instances/Include subclasses 过滤那些,这正是我想要的!【参考方案3】:

YourKit 可以compare heap dumps。

【讨论】:

答案包含死链接。请考虑将链接替换为yourkit的内容,以防止由于网站重构导致死链接(yourkit.com/docs/java/help/compare_snapshots.jsp)

以上是关于比较 Java 内存堆转储:Java 桌面应用程序的内存分析 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Java 堆转储大小比已用内存小得多?

在大型 Java 堆转储中查找内存泄漏的方法

内存不足时的 Java EE 堆转储

Java 本机内存跟踪堆提交的数量远远超过堆转储的总数

创建和分析 Java 堆转储(Heap Dumps)

分析大型 Java 堆转储 - 内存错误