【问题标题】:How to read "Merge Shortest Paths to GC Roots" screen of Eclipse Memory Analyzer?如何阅读 Eclipse Memory Analyzer 的“Merge Shortest Paths to GC Roots”屏幕?
【发布时间】:2016-01-09 12:13:44
【问题描述】:

我正在努力解决这个问题

java.lang.OutOfMemoryError: Metaspace

在重新部署时,在 Tomcat 8.0.18 上运行 Web 应用程序(Apache Roller、Java EE weblogger 软件:https://roller.apache.org)。

我知道问题的原因可以通过 Eclipse 内存分析器找到,所以我在 OOME 时得到了一个堆转储,它由运行的 JVM 自动生成

-XX:+HeapDumpOnOutOfMemoryError.

我可以看到有 4 个 WebappClassLoader 实例应该被垃圾回收。但我不确定为什么这些实例没有被垃圾收集。

所以这是我在Merge Shortest Paths to GC Roots => exclude all phantom/weak/soft/etc. references 屏幕中针对每个WebappClassLoader 实例提出的问题:

  1. 这是否意味着 PostgreSQL JDBC 驱动程序(部署在服务器端)引用了 RollerContext?

  2. 这看起来像SoftEntryReference 的一个实例引用了WebappClassLoader,但我猜它不是一个强引用,所以它不会阻止WebappClassLoader 被垃圾收集。我错了吗?

  3. 我不知道这是什么意思...这是什么意思? WebappClassLoader 本身是否防止被垃圾收集?

  4. 就像我在 2 中写的那样,我想它应该被垃圾收集,因为它被 SoftReference 引用。我错了吗?

【问题讨论】:

    标签: java tomcat memory-leaks garbage-collection classloader


    【解决方案1】:

    这是否意味着 PostgreSQL JDBC 驱动程序(部署在服务器端)引用了 RollerContext?

    是的,看起来是这样。特别是通过静态变量中保存的异常对象的回溯。

    Merge Shortest Paths to GC Roots => 排除所有 phantom/weak/soft/etc。参考文献

    [...]

    这看起来像 SoftEntryReference 的一个实例有对 WebappClassLoader 的引用,但我猜它不是强引用

    [...]

    就像我在 2 中写的那样,我想它应该被垃圾收集,因为它被 SoftReference 引用。我错了吗?

    你错了。

    就垃圾收集器而言,您并没有看到软引用。软引用对象中只有一个字段不是强字段,即referent 字段。

    查看 JDK 的 java.lang.ref.Reference<T> 类内部,您会看到还有其他字段。您还会注意到SoftReference 是可子类化的,因此可以有其他字段。所有非引用字段都是强引用。

    MAT 表示您正在查看的内容由 discovered 字段链保存,这意味着引用对象肯定是活着的,即使它们的引用对象可能已被回收。

    我不知道这是什么意思...这是什么意思? WebappClassLoader 本身是否防止被垃圾收集?

    eclipse docs 对此进行了解释:它是一个 GC 根,因为该对象上持有一个锁,并且它当前由本机代码处理,例如JNI。

    这是"eclipse mat busy monitor" 的第一个谷歌搜索结果。请做你的研究。

    【讨论】:

    • 至于1,现在我怀疑是JDBC驱动的bug,所以我向pgsql-jdbc邮件列表报告了它:postgresql.org/message-id/561B9D78.8090106@nailedtothex.org。至于其他问题,我通过您的精彩解释了解,但仍然不知道是什么使这些强引用或忙碌监视器。你怎么看?
    • 4 由 thread-locals(记录器调度程序线程)保持活动状态。用新线程替换线程应该可以解决这个问题,因此应该关闭其线程池。其中一个类加载器可能是最新的,即应该还活着的。如果软引用被未耗尽的引用队列使用,则它们可能会持续存在。您可能必须探索到根的最短路径之外的对象图,以查看这些对象属于什么。 IE。最短路径可能只是巧合/暂时的,而其他一些通往 GC 根的路径使其长期保持活力。
    • 作为最后的手段,总是可以选择使用反射来挖掘引用并排除那些麻烦的。但是当你进行反射的库发生变化时,这很容易出错和脆弱。
    • 现在我猜这可能与 Google Guice 的问题有关,该问题在与 Web 应用程序一起部署时导致类加载器泄漏(例如 stackoverflow.com/questions/8842256/…)。如果我可以进一步调查,我会报告它。
    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2022-08-08
    • 2021-08-26
    • 2012-04-11
    • 2012-09-24
    相关资源
    最近更新 更多