【问题标题】:Which thread triggered an OutOfMemoryException heap dump哪个线程触发了 OutOfMemoryException 堆转储
【发布时间】:2016-10-07 11:34:33
【问题描述】:

我有一个在 JVM 7 上运行的 JBoss 4.2.1 应用程序,它在抛出 OutOfMemoryExceptions 时触发了堆转储。我为 jvm 配置了以下开关:

-Xms1498m -Xmx3000m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError

我正在尝试通读堆转储以找出导致我的 OOME 的确切原因。我看到消耗了大块内存,但它们在某种程度上是意料之中的。我目前正在寻找的是“确凿证据”。

我已经打开了另一个SO issue here,因为我的堆转储中缺少内存,所以我试图弄清楚 OOME 发生时 JVM 在做什么。

堆转储中是否有任何内容可以指示哪个线程触发了 OOME?更具体地说,触发我的 OOME 的呼叫在做什么?我意识到并理解,在内存泄漏的情况下,这可能是在追踪错误的线索,但我正在寻找是否看到是哪个线程导致了异常。

到底有没有用MAT看这个?

【问题讨论】:

    标签: java heap-dump eclipse-memory-analyzer


    【解决方案1】:

    您是否检查过 MAT 中的线程概述?

    它不会告诉你触发 OOME 的线程,但会提供有关保留堆的信息。

    【讨论】:

    • 是的 - 我一直在看线程概述;谢谢。但它并没有告诉我哪个线程触发了 OOME - 只是哪些线程正在执行什么。鉴于我列出了 258 个线程,因此很难查看每个线程以确定每个线程在做什么。我可以按保留堆大小进行排序,但这只是告诉我哪个线程消耗的内存最多。它没有告诉我是哪个线程导致我的 JVM 崩溃。
    • 你是否看到类似
      Exception in thread "main": java.lang.OutOfMemoryError in your stack trace?
    • 很遗憾没有。我只看到堆栈跟踪和原因(由:java.lang.OutOfMemoryError:Java 堆空间引起),但没有看到有问题的线程名称/编号。
    【解决方案2】:

    我们实际上并不关心导致OOME 的线程,因为它不能证明任何事情,考虑一个线程执行一个没有泄漏的简单任务,如果堆已经快满了并且这个线程甚至创建了一个小Object 它可能会导致OOME 而不是内存泄漏的根本原因。

    关于您的实际问题,我不相信您可以从堆转储中知道哪个 Thread 导致了 OOME,唯一的方法是在 JVM 将堆栈跟踪打印到时检查您的控制台或日志文件OOME 上的标准输出。

    【讨论】:

    • 如上所述,我意识到在OOME 中,导致OOME 的线程可能无法证明任何事情。但是,我试图关联几个不同的转储,如果我能看到导致OOME 的模式(例如:一个线程试图分配巨大的内存块),它可能有助于缩小我的关注范围。当然,正如您所提到的,这可能与此无关。
    • 阅读这篇文章可能会有所帮助stackoverflow.com/questions/37593549/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 2011-02-02
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多