11

我有一个案例,我需要在我的应用程序中创建很多类加载器,以便在用户提供的脚本运行时临时使一些代码可见。我URLClassLoader为此使用了一个,它工作得很好。

当脚本终止时,我想“卸载”或“关闭”类加载器以释放资源。

将对类加载器的引用设置为 是否足够null?我特别想知道我是否最终会用完文件句柄,因为额外的类在 JAR 文件中。

PS:必须使用 Java 5 及更高版本。是的,我知道...

4

6 回答 6

8

有点晚了,但希望这对以后来这个问题的人(比如我)有所帮助。

在 Java 7 中,已将close()方法添加到 URLClassLoader,这正是 OP 所要求的。

编辑(感谢@Hot Licks)好的,所以这不是OP所要求的。它不会释放所有资源,也不会使资源和加载器成为可收集的。它只是防止使用类加载器加载更多资源。但是,它确实会关闭使用 .jar 文件加载的 jar 文件。URLClassLoader

于 2014-06-28T06:30:30.047 回答
5

如果您不能使用 Java7 并且它是 close() 方法,请使用反射关闭类加载器的所有打开的 JAR 档案,如下所示:

public void close() {
try {
   Class clazz = java.net.URLClassLoader.class;
   java.lang.reflect.Field ucp = clazz.getDeclaredField("ucp");
   ucp.setAccessible(true);
   Object sun_misc_URLClassPath = ucp.get(this);
   java.lang.reflect.Field loaders = 
      sun_misc_URLClassPath.getClass().getDeclaredField("loaders");
   loaders.setAccessible(true);
   Object java_util_Collection = loaders.get(sun_misc_URLClassPath);
   for (Object sun_misc_URLClassPath_JarLoader :
        ((java.util.Collection) java_util_Collection).toArray()) {
      try {
         java.lang.reflect.Field loader = 
            sun_misc_URLClassPath_JarLoader.getClass().getDeclaredField("jar");
         loader.setAccessible(true);
         Object java_util_jar_JarFile = 
            loader.get(sun_misc_URLClassPath_JarLoader);
         ((java.util.jar.JarFile) java_util_jar_JarFile).close();
      } catch (Throwable t) {
         // if we got this far, this is probably not a JAR loader so skip it
      }
   }
} catch (Throwable t) {
   // probably not a SUN VM
}
return;
}
于 2015-06-29T11:38:43.873 回答
4

当类加载器加载的所有类不再有任何引用,并且对类加载器本身的所有引用都已被擦除时,类加载器及其加载的类将作为一个组进行垃圾回收。

请注意,这取决于是否设置了导致未引用类被卸载的 JVM 属性。它在大多数环境中默认设置,但在某些嵌入式情况下可能不是。

[请注意,删除对类的引用并非易事。任何其他按名称引用它的类当然会阻止删除。所以这个类必须使用 ClassLoader.findClass 或类似的东西来加载。]

于 2011-09-20T16:00:50.773 回答
3

如果您不再从该类加载器加载类(和对象),并且您不保留对该类加载器的任何引用,它将由垃圾收集器自动处理。

于 2011-09-20T15:53:35.013 回答
1

URL 类加载器或其任何父类中没有 close() 方法,所以你不走运。

GC不应该处理这个吗?

于 2011-09-20T15:50:31.767 回答
0

我扩展了 URLClassLoader,做了一个基于 Java 7s 的 close 方法。我想在我的 iPad 2 上开发我的 IRC 机器人,所以我做了需要做的事情。现在我的插件系统在 Java 6 和 7 上是稳定的,万岁。

于 2012-07-04T20:04:59.640 回答