gpt4 book ai didi

java - 即使没有 GC 根,类加载器也不会被垃圾回收

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:02:52 27 4
gpt4 key购买 nike

我们有一个在 Glassfish V2.1.1 下运行的复杂应用程序。为了能够动态加载我们的代码,我们实现了一个能够重新定义类的 CustomClassloader。行为非常简单:当动态加载的类发生变化时,CustomClassloader 的当前实例将被“丢弃”,并创建一个新实例来重新定义所需的类。

除了同一个类被重新加载几次后(因此每次创建一个新的 CustomClassloader),这工作得很好,我们得到一个 PermGen 空间错误,因为 CustomClassloader 的其他实例没有被垃圾收集。 (该类应该只有一个实例)

我尝试了不同的方法来追踪泄漏的位置:

  1. visualvm => 我进行堆转储并提取 CustomClassloader 的所有实例。我可以看到它们都没有最终确定。当我检查最近的 GC 根目录时,visualvm 告诉我没有(最后一个实例除外,因为它是“真正”使用过的根目录)。
  2. jmap/jhat => 它给了我几乎相同的结果:我看到了 CustomClassloader 的所有实例,然后当我单击链接以查看其中一个的引用在哪里时,我得到一个空白页面,这意味着没有...<
  3. Eclipse Memory Analyzer Tool => 当我运行以下 OQL 查询时,我得到了一个奇怪的结果:SELECT c FROM INSTANCEOF my.package.CustomClassloader c只有一个结果,表明只有一个实例显然是正确的。

我也检查了这个link并在创建新的 CustomClassloader 时实现了一些资源释放,但没有任何变化:PermGen 内存仍在增加。

所以我可能遗漏了一些东西,第 (1-2) 点和 (3) 点之间的差异显示了一些我不理解的东西。我在哪里可以了解问题出在哪里?由于我遵循的所有教程都展示了如何使用“搜索最近的 GC 根”功能搜索泄漏的引用(在我的例子中没有),我不知道如何跟踪错误。

编辑 1:我上传了一个堆转储示例 here .可以使用以下查询在 visualvm 中选择未卸载的 ClassLoader:select s from saierp.core.framework.system.SAITaskClassLoader s可以看到有 4 个实例,前三个应该被收集,因为没有 GC 根......某处一定有引用,但我不知道如何搜索它。欢迎任何提示:)

编辑 2:经过一些更深入的测试后,我看到了一个非常奇怪的模式。泄漏似乎取决于 OpenJPA 正在加载的数据:如果没有加载新数据,则可以对类加载器进行 GC,否则不会。这是我在创建新的 SAITaskClassLoader 以“清除”旧的时使用的代码:

PCRegistry.deRegister(cl);
LogFactory.release(cl);
ResourceBundle.clearCache(cl);
Introspector.flushCaches();

= 模式 1(类加载器被 GCed):=

  1. 新的 SAITaskClassLoader
  2. 加载数据 D1、D2、...、Dn
  3. 新的 SAITaskClassLoader
  4. 加载数据 D1、D2、...、Dn
  5. ...

cl-gc

= 模式 2(类加载器未被 GC):=

  1. 新的 SAITaskClassLoader
  2. 加载数据 D1、D2、D3
  3. 新的 SAITaskClassLoader
  4. 加载数据 D3、D4、D5
  5. 新的 SAITaskClassLoader
  6. 加载数据 D5、D6、D7
  7. ...

cl-nogc

在所有情况下,被清除的SAITaskClassLoader都没有GC根。我们正在使用 OpenJPA 1.2.1。

谢谢和最好的问候

最佳答案

如果没有 CustomClassLoader 的源代码片段或实际的堆转储,将很难找到问题所在。您的 CustomClassLoader 不能是单例。如果是,则您的设计无法正常工作(或者我遗漏了一些东西)。

您需要获取 CustomClassLoader 类型的 ClassLoader 实例列表,并追踪对这些对象的引用。

这些帖子可能会帮助您进一步分析它并深入了解寻找 ClassLoader 泄漏的黑暗细节:

关于java - 即使没有 GC 根,类加载器也不会被垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13778822/

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