诊断Java内存问题的策略

时间:2009-01-06 21:36:02

标签: java memory garbage-collection jconsole

我的任务是调试Java(J2SE)应用程序,该应用程序在一段时间的活动开始后抛出OutOfMemory异常。我是Java新手,但有编程经验。我有兴趣就诊断这样的问题的好方法得到你的意见吗?

到目前为止,我已经使用JConsole来了解正在发生的事情。我有预感,有些物品没有正确释放,因此在垃圾收集过程中没有被清理干净。

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

5 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

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

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

有关heap dump

的更多信息,请参阅此文章

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

答案 2 :(得分:2)

最新版本的Sun JDK包括VisualVM,它本身就是Netbeans的分析器。它的效果非常好。

答案 3 :(得分:1)

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

例如,我必须解决的最新项目抛出OutOfMemoryError异常,并且在启动YourKit之后我意识到大多数内存实际上被分配给某些ehcache“LFU”类,关键是我们指定了某个特定的负载POJO要缓存在内存中,但我们没有指定足够的-Xms和-Xmx(起始和最大JVM内存分配)。

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

更新,请参阅https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

答案 4 :(得分:-1)

您还可以在应用程序的线程中添加“UnhandledExceptionHandler”。这将捕获'未捕获'异常,如内存不足错误,并且您至少会知道抛出异常的位置。通常这不是问题,但是不能满足的“新”。作为一项规则,我总是将UnhandledExceptionHandler添加到一个线程,如果没有别的东西可以添加日志记录。