2009-01-06 93 views
4

我的任务是调试Java(J2SE)应用程序,该应用程序在一段时间的活动后开始抛出OutOfMemory异常。我是Java新手,但有编程经验。我有兴趣了解如何诊断此类问题的好方法?诊断Java内存问题的策略

到目前为止,我已经聘用了JConsole来了解正在发生的事情。我有一种预感,那就是有没有被正确释放的对象,因此在垃圾回收期间没有被清理。

是否有任何工具可用于获取对象生态系统的图片?你会从哪里开始?

回答

4

我会从一个适当的Java分析器开始。 JConsole是免费的,但它远不及那些花钱的功能。我使用JProfiler,这是非常值得的钱。有关更多选项和意见,请参见https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

+0

谢谢你的抬头。花了大约30分钟配置探查器集成后,我能够在大约5分钟内找到内存泄漏的来源。感谢这个建议。 – Matty 2009-01-07 16:24:19

4

尝试使用Eclipse Memory Analyzer或任何其他可以处理Java堆转储的工具,然后使用运行内存不足时生成堆转储的功能来运行应用程序。

然后分析堆转储并查找可疑高对象数。

有关heap dump的更多信息,请参阅这篇文章。

编辑:另外,请注意,您的应用程序可能只是合法需要比您最初想象的更多的内存。您可以尝试将java最小和最大内存分配增加到更大的内存,然后查看您的应用程序是无限期运行还是稍微进一步。

+0

我希望我可以在另一个线程中直接链接到我对EMA的评论,但是我不能推荐这个。 EMA能够在不到5分钟的时间内为我打开一个大约400mb的堆转储日志文件,而jhat花了70多分钟在它崩溃JVM之前阅读它(从未能够完全打开它)。 – 2009-06-18 18:39:01

1

http://www.yourkit.com/download/index.jsp是您需要的唯一工具。 您可以在(1)应用程序开始时间拍摄快照,以及(2)在运行应用程序N段时间之后,然后比较快照以查看内存分配的位置。它还会对OutOfMemoryError拍摄快照,以便您可以将此快照与(1)进行比较。

例如,我必须排除故障的最新项目抛出OutOfMemoryError异常,并且在启动YourKit之后,我意识到大部分内存实际上正被分配给一些ehcache“LFU”类,重点是我们指定了某些POJO要缓存在内存中,但我们没有指定足够的-Xms和-Xmx(开始和最大JVM内存分配)。

我也使用过Linux的vmstat一些Linux平台没有启用足够的交换,或者不分配连续的内存块,然后有(与JDK捆绑在一起的)jstat

UPDATE看到https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

-1

您还可以添加一个 “UnhandledExceptionHandler” 到应用程序的线程。这将捕获'未捕获'异常,就像内存不足错误,并且您至少会知道引发异常的位置。通常情况下,这不是问题,而是无法满足的'新'。作为一个规则,我总是添加UnhandledExceptionHandler到一个线程,如果没有别的要添加日志记录。

2

最新版本的Sun JDK包含VisualVM,它本身就是Netbeans分析器。它工作得很好。