什么时候以及如何将Java类加载器标记为垃圾回收?

我们正在创建多个子类加载器,以将多个子应用程序加载到Java应用程序“容器”中,从而对热部署进行原型设计。当特定类加载器的类路径发生更改时(即,添加,删除,更新了jar),旧的类加载器将被丢弃(未引用),并为jar的新类路径创建新的类加载器。

更新类路径后,触发热部署,我们进行了堆转储。堆转储(使用内存分析器)表明旧的类加载器未在进行垃圾回收。父类加载器中的某些类正在缓存旧的类加载器。调用了以下操作来清除这些缓存:

java.lang.ResourceBundle.clearCache(classLoader);

org.apache.commons.logging.LogFactory.release(classLoader);

java.beans.Introspector.flushCaches();

即使清除了上面的缓存,旧的类加载器仍然没有被垃圾回收。对类加载器的其余引用包括以下内容:

  • 类加载器加载的类
  • java.lang.Package由类加载器本身创建
  • 由类加载器本身创建的java.lang.ProtectionDomain

以上所有内容都是类加载器中的循环引用,应触发垃圾回收。我不确定为什么不是这样。有人知道为什么即使使用循环引用仍旧不对旧的类加载器进行垃圾回收吗?

回答:

我一直听说Classloader卸货是有问题的。从理论上讲,它们是在不引用对象实例且不需要类卸载时进行垃圾收集的,但实际上似乎存在更多问题。细微的引用可能会泄漏并阻止对其Classloader进行回收。在应用程序服务器中,经过无数次重新部署周期后,有时我得到了OutOfMemoryError:

PermGen space

这么说,我想在某处有一个讨厌的引用阻止了它的收集-内存分析器可能未正确遵循链接。似乎所有这些事情都可能发生,如这些文章中所述:

  • 类加载器泄漏:可怕的PermGen空间异常
  • 如何修复可怕的PermGen空间异常

另外,我也不知道您在做什么,但是如果您可以等待JDK

7,则可以查看一下AnonymousClassLoader。将介绍它们以更好地支持动态语言,如本博文所述:

  • InvokeDynamic的初衷

希望对您有帮助。

以上是 什么时候以及如何将Java类加载器标记为垃圾回收? 的全部内容, 来源链接: utcz.com/qa/429098.html

回到顶部