诊断Java内存问题的策略

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

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

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

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

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

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

有关堆转储的更多信息,请参阅此文章。

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

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

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

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

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

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

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