URLClassLoader会“挂住”所有它已经打开了的在classpath上的文件

嗯,这问题虽然很久以前就知道了,但最近一个功能正好需要让ClassLoader有些灵活性,就又栽在这里了。顺便把这个问题记下来。

Sun的JDK里最重要的两种ClassLoader,sun.misc.Launcher.ExtClassLoader和sun.misc.Launcher.AppClassLoader都是继承了 URLClassLoader的(bootstrap ClassLoader并不是Java程序可见的ClassLoader,不算在内;它甚至不继承ClassLoader这个基类,根本不是一个Java object)。别的一些自定义ClassLoader为了实现方便也会继承URLClassLoader,例如 GroovyClassLoader

但就是这么重要的URLClassLoader却一直有一个特性:它一旦打开了它所知的classpath上的文件就会把那些文件全部锁住,直到它被卸载前都不会释放掉。但是ClassLoader什么时候才被释放这就无法预测了,里面引用的JarFile的finalizer什么时候被调用又得看RP,诶……

在Java 7当中 URLClassLoader新实现了 Closeable接口,添加了一个 close()方法,专门用于处理这个问题。在调用了某个URLClassLoader实例上的close()方法后,该实例就无法再用于加载类或资源;原本已经打开的类或资源仍然是可用的。

但在Java 7正式发布之前,要是想修改已经被URLClassLoader打开的JAR包就没好办法了。

你可能感兴趣的:(java,html,.net,sun,groovy)