我有一个需求,需要在我的应用程序中创建大量的类加载器,以便在用户提供的脚本运行时暂时使一些代码可见。我使用URLClassLoader
实现了这个功能,并且效果很好。
当脚本终止时,我想要“卸载”或“关闭”类加载器以释放资源。
将类加载器的引用设置为null
是否足够?我特别担心因为额外的类在JAR文件中而最终耗尽文件句柄。
注:必须能够在Java 5及以上版本中使用。是的,我知道...
我有一个需求,需要在我的应用程序中创建大量的类加载器,以便在用户提供的脚本运行时暂时使一些代码可见。我使用URLClassLoader
实现了这个功能,并且效果很好。
当脚本终止时,我想要“卸载”或“关闭”类加载器以释放资源。
将类加载器的引用设置为null
是否足够?我特别担心因为额外的类在JAR文件中而最终耗尽文件句柄。
注:必须能够在Java 5及以上版本中使用。是的,我知道...
URLClassLoader
加载的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;
}
lsof
显示的许多JAR文件的FD。您的代码解决了我的问题! - waltersuURL类加载器或其任何父类中都没有close()方法,所以你很遗憾。
难道不应该由GC处理吗?
我扩展了URLClassLoader并基于Java 7创建了一个close方法。我想在我的iPad 2上开发我的IRC机器人,所以我做了必要的事情。现在我的插件系统在Java 6和7上都很稳定,太棒了。
close()
方法做什么? - Aaron Digulla