比较java内存堆转储:Java桌面应用程序的内存分析

时间:2009-11-21 01:52:39

标签: java memory-management profiling

这是一个更具体的问题,可以跟进another question that I have asked recently。这个问题的正确答案也会为之前的问题找到正确答案(因为那仍然处于不确定状态)!

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

  1. 将新的内存分析器附加到Netbeans项目
  2. 在几个精心选择的代码行中定义分析点,并将它们设置为触发内存堆转储
  3. 以分析模式运行应用程序
  4. 最终结果是我在*.hprof个文件中保存了几个内存转储。 Netbeans IDE允许我仔细阅读这些内存转储的内容(基本排序和搜索),甚至让我遍历堆,通过查看每个实例中包含的引用,以及其他对象引用每个实例。这一切都很好,我已经能够确定1或2个相当明显的内存泄漏,并纠正了迄今为止大约15%的问题。

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

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

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

    谢谢!

3 个答案:

答案 0 :(得分:15)

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

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

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

答案 1 :(得分:14)

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

答案 2 :(得分:5)

YourKit可以compare heap dumps