我该如何在Java中查看我的堆中有什么?

22

我正在开发一款Java应用程序,出现了内存泄漏的情况。在运行JUnit测试套件时,经常会随机抛出内存不足异常(java.lang.OutOfMemoryError)。

有哪些工具可以用来检查我的Java应用程序的堆,以查看是什么占用了所有的堆空间,从而找出是什么导致对象无法被垃圾回收。

8个回答

30

VisualVM已经包含在最新版本的Java中。您可以使用它来创建堆转储,并查看其中的对象。

另外,您也可以使用jmap(位于jdk/bin目录中)来创建一个命令行堆转储:

jmap -dump:format=b,file=heap.bin <pid>

您甚至可以使用此功能快速获取所有对象的直方图。

jmap -histo <pid>
我可以推荐Eclipse Memory Analyzer(http://eclipse.org/mat)来进行堆转储的高级分析。它让你能够准确找出为什么某个对象或一组对象依然存在。这里有一篇博客文章介绍了Memory Analyzer的功能:http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/27/automated-heap-dump-analysis-finding-memory-leaks-with-one-click/

Visual VM和Netbeans Profiler允许您执行与EMA相同的操作。 - James Schek
1
我不了解NetBeans,但我肯定在Visual VM中没有找到“最短路径到GC根”。 - Tom

7
如果你需要免费的东西,可以尝试使用VisualVM
根据该项目的描述:
VisualVM是一个集成命令行JDK工具和轻量级性能分析功能的可视化工具。旨在同时用于开发和生产时间使用。

3

这是一个比较老的问题。很多人可能从原来的回答以后开始使用IntelliJ。 IntelliJ有一个插件可以显示内存使用情况,叫做JVM Debugger Memory View


在试用不同的工具后,我发现IntelliJ也有一个VisualVM插件(在另一个答案中提到)。那个组合最终对我来说效果最好。 - mkasberg

2

使用Eclipse Memory Analyzer

在分析堆转储时,我没有发现其他工具的功能、性能和价格(免费且开源)与它相匹配。


1

1

0
如果您正在使用支持GTK的系统,可以尝试使用JMP

0
您可以尝试使用 JRockit Mission Control 工具套件中的内存泄漏检测器。它允许您在 JVM 运行时检查堆。您不需要一直拍摄快照。您只需在线连接到 JVM,然后查看垃圾回收之间堆的变化。您还可以图形化地检查对象、跟踪引用并获取分配对象的当前应用程序的堆栈跟踪。这里有一个简要 introduction
该工具可免费用于开发,并可在 此处 下载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接