Java类加载器是在何时及如何被标记为垃圾回收的?

29 浏览
0 Comments

Java类加载器是在何时及如何被标记为垃圾回收的?

我们正在创建多个子类加载器将多个子应用程序加载到Java应用程序“容器”中,原型化热部署。当特定类加载器的类路径发生更改时(例如添加、删除、更新JAR包),旧的类加载器将被丢弃(未引用),并为新的JAR包类路径创建新的类加载器。

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

java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();

即使清除了上述缓存,旧的类加载器仍然未被垃圾收集。剩余的对类加载器的引用包括以下内容:

- 类加载器加载的类

- 类加载器本身创建的java.lang.Package

- 类加载器本身创建的java.lang.ProtectionDomain

所有这些都是类加载器内的循环引用,应该触发垃圾收集。我不确定为什么没有触发,有谁知道为什么即使有循环引用,旧的类加载器仍未被垃圾收集吗?

admin 更改状态以发布 2023年5月24日
0
0 Comments

我一直听说Classloader的卸载很麻烦。它们在没有对象实例的引用和不需要类卸载时理论上可以被垃圾回收,但实际上似乎更加困难。微妙的引用可能泄漏并防止Classloader被回收。在应用服务器中,经过数次重新部署周期后,有时会出现OutOfMemoryError: PermGen space

所有这些都是想说,我想有一个不好的引用阻止了它被回收--也许内存分析器没有正确地跟随链接。正如这些文章所描述的那样,所有这一切似乎都可能发生:

另外,我不知道你到底在做什么,但如果你可以等到JDK 7,你可以看看AnonymousClassLoader。它们将被引入以更好地支持动态语言,如本文章所述:

我希望这会对你有所帮助。

0