解决Java内存泄漏的一般策略?

我有一个独立的程序,我本地运行,这意味着一个服务器types的程序运行24/7。 最近我发现它有内存泄漏,现在我们唯一的解决scheme是每4小时重新启动一次。 寻找这种内存泄漏的最佳方式是什么? 我们应该使用哪种工具和方法?

如果您使用的是Sun的Java,并且至less使用了Java 6 update 10(即最新版本),那么请尝试在程序运行的同一台机器上运行JDK中的jvisualvm,然后附加并启用分析。

这很可能是最简单的入门方法。

当讨论内存问题时,我使用SAP内存分析器 Eclipse内存分析器(MAT) ,一个堆转储分析工具。

Memory Analyzer提供了一个通用工具包来分析Java堆转储。 除了堆走和保留大小的快速计算,Eclipse工具报告泄漏的嫌疑人和内存消耗的反模式。 应用的主要领域是内存不足错误和高内存消耗。

该项目由SAP发起,目前已经开源,现在被称为Eclipse Memory Analyzer 。 查看入门页面,尤其是查找内存泄漏部分(我在下面粘贴,因为我修复了一些链接):

通过运行泄漏报告开始自动检查内存泄漏。

此博客详细信息如何查找泄漏的工作台窗口 。

内存分析器在SAP上成长起来。 当时,Krum在博客中介绍了如何使用SAP内存分析器查找内存泄漏 。 内容仍然相关!

对于堆转储分析(和内存泄漏),这可能是最好的工具(甚至是金钱)。

PS:我不为SAP / IBM / Eclipse工作,我只是一个非常高兴的MAT用户,有积极的反馈。

你需要一个内存分析器 。 我build议尝试Netbeans分析器 。

您可能会查找JMX和Java附带的jconsole应用程序。 你可以直接得到一些有趣的统计数据,并且为你的类增加一些简单的工具可以提供更多的东西。

一种方法是定期进行堆转储,然后趋向您的类的实例计数,以尝试确定哪些对象始终创build但未收集。

另一个将closures您的应用程序的部分,以试图缩小问题的位置。

看看像jmap和jhat这样的工具。

正如已经说过的,jvisualvm是一个很好的开始,但是一旦你知道什么是泄漏,你可能需要find什么是持有引用问题的对象,我build议jmap和jhat,例如

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

 jhat heap.dump.out 

从jvisualvm很容易find<pid>。 然后在浏览器中导航到localhost:7000并开始探索。