gpt4 book ai didi

java - 弱引用持有的类加载器?

转载 作者:搜寻专家 更新时间:2023-10-30 21:32:58 25 4
gpt4 key购买 nike

我一直在与一些内存泄漏作斗争,目前我对这个问题感到困惑。有一个应该被垃圾收集的 Web 应用程序类加载器,但它不是(即使在我修复了几个漏洞之后)。我用 jmap 转储堆并用 jhat 浏览它,找到类加载器并检查根集引用。

如果我排除弱引用,列表是空的!这怎么可能,因为仅由弱引用持有的对象应该被垃圾收集? (我在jconsole中进行了多次GC)

如果我包含弱引用,我会得到一个引用列表,所有引用都来自以下字段之一:

  • java.lang.reflect.Proxy.loaderToCache
  • java.lang.reflect.Proxy.proxyClasses
  • java.io.ObjectStreamClass$Caches.localDescs
  • java.io.ObjectStreamClass$Caches.reflectors
  • java.lang.ref.Finalizer.unfinalized

我找不到任何理由说明为什么这些引用会阻止类加载器的垃圾回收。这是一个gc错误吗?特殊无证案件? jmap/jhat 错误?或者什么?

最奇怪的是......在闲置并时不时地进行 gc-ing 大约 40 分钟后,没有任何更改,它最终决定卸载类并收集类加载器。

注意:

如果您声明延迟收集类加载器或弱引用,请具体说明发生的情况,理想情况下:

  • 提供指向支持您的主张的权威文章的链接
  • 提供一个演示该行为的示例程序

如果您认为行为依赖于实现,那么请关注 oracle 或 icedtea jvm 版本 6 或 7 中发生的情况(选择其中任何一个并具体说明)。

我真的很想弄个水落石出。实际上,我付出了一些努力在测试程序中重现该问题,但我失败了——类加载器每次都会立即收集到 System.gc() 上,除非有对它的强引用。

最佳答案

看起来某处涉及软引用。这是我能找到的关于延迟收集(大约 40 分钟)的唯一解释。我最初认为软引用会一直保留到内存用完,但我发现情况并非如此。

来自 this page : "softly reachable objects 将在上次被引用后的一段时间内保持 Activity 状态。默认值是堆中每兆字节的生命周期一秒。可以使用 -XX:SoftRefLRUPolicyMSPerMB 标志调整此值"

所以我将该标志调整为 1,类加载器在几秒钟内就被收集了!!

我认为软引用来自 ObjectStreamClass。问题是为什么 jhat 没有在根集引用中显示它。是因为不强不弱吗?或者因为它已经从相同的静态字段中找到了弱引用?还是别的什么原因?无论哪种方式,我认为这需要在 jhat 中进行改进。

关于java - 弱引用持有的类加载器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20337171/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com