我正在使用扩展 URLClassLoader 的自定义类加载器。我将一些类加载到我的自定义类加载器中并执行一些任务。任务完成后,我想处理类加载器。我尝试通过将引用设置为 null 来做到这一点。
但这不会垃圾收集类加载器。
有没有办法可以帮助我想要实现的目标?
我正在使用扩展 URLClassLoader 的自定义类加载器。我将一些类加载到我的自定义类加载器中并执行一些任务。任务完成后,我想处理类加载器。我尝试通过将引用设置为 null 来做到这一点。
但这不会垃圾收集类加载器。
有没有办法可以帮助我想要实现的目标?
基本上,正如@invariant 已经指出的那样,取消引用由特定类加载器加载的所有类应该使该类加载器可以被垃圾回收。但是,(至少)有一个例外:如果一个类被序列化,则该类(以及它的类加载器)在内部被 引用ObjectStreamClass
,这是一个原始类,因此永远不会被垃圾收集。所以在这种情况下,类加载器也不能被垃圾回收,直到整个 JVM 终止。
请参阅此处的完整说明,在“与垃圾收集和序列化相关的问题”部分。
来自ClassLoader 文档:Every Class object contains a reference to the ClassLoader that defined it
。这会阻止您的装载机被收集。您还必须取消对这些类的所有引用和这些类的实例。
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4950148上有一个 6 年前的错误,这似乎是您想要的。不幸的是,似乎还没有实现这样的功能......
在 ClassLoader 不再创建类的实例后,ClassLoader 将被垃圾回收。有一个旧错误 ( 4950148 ) 与无法显式处理 ClassLoader 相关,这会导致文件锁定等问题。
这现在已在 JDK 7 中得到修复,它添加了URLClassLoader.close()方法。
只要这个类加载器加载的任何类被引用,类加载器就不会被垃圾回收。所以类加载器将在以下情况下被删除:对类加载器的所有直接引用都为空,对由该类加载器加载的类的所有引用以及对这些类的实例的所有引用。然后可以在垃圾收集器的下一次运行时将其转储。