【问题标题】:Detect root cause in heap dumps in java在java中检测堆转储中的根本原因
【发布时间】:2012-08-03 06:57:34
【问题描述】:

在 java 堆转储中,我如何确切知道代码中的哪个位置/哪个线程导致了转储?

【问题讨论】:

  • 原因是任何正在使用内存的东西(很多)您正在寻找的是使用比您认为应该更多的内存的对象。我使用 YourKit 来跟踪分配,以便查看哪些代码创建的数据最多(或我关心的数据)
  • 如果应用程序运行正常,原因可能是最大堆大小太小。

标签: java heap-dump


【解决方案1】:

用于读取内存转储:

我建议你尝试来自here的“eclipse 内存分析器”

另一个选项(免费)是使用 JVisualVM 打开它(可在 $JAVA_HOME/bin 获得) jhat 也很酷,但已经被推荐了:)

现在,您要问的是导致内存堆转储的线程,而不是如何进行内存转储... 这取决于您如何获得内存转储。 获取转储的方法有多种。

  1. 在您的进程中,一旦遇到 OutOfMemory 错误,您可以指示 JVM 生成内存转储,在这种情况下,我相信它将是 JVM 本身。

  2. 如果你有一个 JMX 服务器和你的 JVM 一起运行,你可以从 MBean 触发堆转储创建 Example

  3. 您甚至可以在应用程序外部使用系统调用(在 linux 上):kill -3 _YOUR_JAVA_PROCESS_ID_ 将生成堆转储。

但我很难想象你为什么需要这样的信息。稍后在 cmets 中,您提到了“确切的代码行”,但这些方式通常在您的 JVM 之外......您确定需要一行代码自行生成堆转储,还是您正在尝试找出真正的问题?

希望对你有帮助

【讨论】:

  • 我要问以下问题:有一个堆转储,我如何在其中找到导致错误并因此让 JVM 产生转储的代码和线程中的确切行?
  • 啊,我明白了。所以你有一个错误,通常是OutOfMemory,对吧?在这种情况下,它只是一个堆转储分析。如果您使用 MAT,它将为您识别可能的瓶颈/可疑代码的机会。通常它归结为内存泄漏,但没有灵丹妙药的解决方案。每个系统都不同。试着看看你有多少每种类型的物体,也许有些东西看起来很“奇怪”,你会知道如何继续……
【解决方案2】:

在 java 中,您在某个地方创建对象,在许多地方使用它,然后让 GC 将其收集回来。没有单行导致泄漏。

您应该在 MAP 等工具中寻找对象数量和它们使用的堆。选择每个目标类,看看为什么它们没有被垃圾收集。 (有些人持有比需要更多的参考资料——比如一个静态字段)

您可能会发现此页面上的说明更有用 - http://scn.sap.com/people/krum.tsvetkov/blog/2007/07/02/finding-memory-leaks-with-sap-memory-analyzer(也链接自 MAT 主页)

【讨论】:

    【解决方案3】:

    尝试使用Java Heap Analysis Tool(jhat) 或 jconsole(位于您的 JAVA_HOME\bin 中)。

    【讨论】:

    • 我有兴趣找到确切的代码行。这能做到吗?
    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    相关资源
    最近更新 更多