【问题标题】:How to find a java memory leak如何找到java内存泄漏
【发布时间】:2011-01-09 15:00:27
【问题描述】:

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

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

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

有人知道吗?

【问题讨论】:

  • 你怎么知道内存使用过多是问题所在?你收到OutOfMemoryError了吗?
  • 另见:stackoverflow.com/questions/1473510/…(相关问题面板中的第一个点击...您确实检查了相关问题,对吗?)
  • 根据 danben 的评论:您可能会收到“Out Of Memory”错误,这实际上意味着您超出了正在使用的线程数的限制。也许这就是正在发生的事情,这就是为什么您的分析器没有显示您的内存不足的原因。您提到“将对象设置为 null”表明您没有很好地处理基本概念,因此也许您确实有很多未终止的线程。

标签: java memory-management


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    附加 jvisualvm(在 Java 6 JDK 中)并查看它是否提供 YourKit 不提供的信息(包括分析)。

    【讨论】:

      【解决方案3】:

      听起来您以错误的方式分析某些内容,您可能遗漏了某些内容。

      探查器错过泄漏的情况并不常见,而且这显然足以使您的服务器崩溃。您是否检查过您崩溃的原因确实与内存有关?

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

      【讨论】:

        【解决方案4】:

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

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

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2019-08-20
            • 1970-01-01
            • 2013-04-04
            • 1970-01-01
            • 2018-04-07
            相关资源
            最近更新 更多