如何找到java内存泄漏

时间:2010-01-26 17:40:49

标签: java memory-management

我遇到了Java内存泄漏的问题,由于某种原因,我的探查器(Yourkit)中没有出现这种问题。当我运行我的Java应用程序(具有一些用于侦听,发送和处理数据的线程的服务器)时,似乎每次我获得新连接并且删除此连接时,一些内存不会被清除。至少,这就是Windows(和Linux)所说的。

当我使用我的探查器运行我的应用程序时,它只是以它应该的方式显示内存,当线程关闭时所有内存都被清理。然而,实际上,经过一段时间Java只是崩溃,因为它使用了太多的内存,所以不管我的分析器说什么,我倾向于相信我使用它的Windows和Linux。运行垃圾收集也不会清理内存。

那么这可能是什么?我已经尝试了所有我知道的,关闭线程,将所有对象设置为null,删除每个数组的内容等等。我很确定线程是关闭的,因为eclipse和编译器以及打印输出似乎都证实了这一点。

有没有人有线索?

5 个答案:

答案 0 :(得分:2)

当发生OutOfMemory-Error时,您可以要求VM生成堆转储,然后分析此堆转储。

对于Sun的HotSpot VM,您可以按照here所述请求堆转储生成。

要分析转储,您可以使用jVisualVM或jhat。 (可能有更好的工具,但到目前为止我还没需要它们。)

答案 1 :(得分:1)

使用jvisualvm(在Java 6 JDK中)附加,看看它是否提供了YourKit没有的信息(包括分析)。

答案 2 :(得分:0)

听起来你正在以错误的方式描述某些东西,你可能会遗漏某些东西。

分析器错过泄漏的情况并不常见,而且明显不足以使服务器崩溃。你有没有检查过你与内存相关的崩溃原因?

您可以发布您的代码的可疑部分和一些分析结果吗?

答案 3 :(得分:0)

您可以尝试浏览堆 - 使用jmap创建二进制堆转储,jhat将启动一个允许您浏览堆内容的小型本地服务器。 Eclipse还有一个图形插件,允许您浏览堆。

jmap -dump:format=b,file=FILENAME PID
jhat HEAPFILENAME

这可能不是那么有用,但它是一个开始 - 例如如果你有庞大的字符串映射,那么一堆满是成千上万字符串的堆就不会告诉你哪些映射以及代码的哪些部分是违法者。

如果您正在创建大量线程,您还可以尝试运行jstack,它将告诉您当前在jvm中运行的所有线程的线程状态。

答案 4 :(得分:0)

还有另一个答案,一个不涉及内存泄漏的答案,可能导致Java进程崩溃。堆栈溢出。你的任何线程做任何递归吗?你的代码有没有办法创建一个巨大的调用堆栈?您需要发布崩溃消息,以便我们可以清除各种可能性。