Java classLoader困境与锁定的罐子

时间:2012-06-30 10:17:08

标签: java classloader urlclassloader

我正在玩Java中的classLoaders并注意到一件奇怪的事情。如果classLoader从jar加载一个类,即使你没有引用你的classLoader,这个jar也会被无限期锁定。

在下面的示例中,jar包含一个名为HelloWorld的类。我所做的是尝试通过classLoader加载jar中包含的类,该类动态地添加jar。如果您将skip设置为true而不是致电Class.forName,则可以删除该jar,但如果您不跳过,即使您不引用classLoader({{1}在JVM退出之前,无法删除jar。

为什么?

PS:我使用的是java 6,代码非常冗长,用于测试目的

classLoader = null

2 个答案:

答案 0 :(得分:9)

我找到了答案和解决方法。

基于此article和这个惊人的相关article,使用Class.forName(className, true, classLoader)是一个坏习惯,因为它会使类无限期地缓存在内存中。

解决方案是使用classLoader.loadClass(clasName)代替,然后完成后,取消引用classLoader并使用以下方法调用垃圾收集器:

classLoader = null;
System.gc();

希望这有助于他人! :)

背景信息:

我的项目很复杂:我们有一台GWT服务器充当另一台服务器的RMI客户端。因此,要创建实例,GWT需要从服务器下载类并加载它们。稍后,GWT会将实例重新发送到服务器,以使用Hibernate将它们保存在数据库中。为了支持热部署,我们选择动态类加载,用户上传jar并通知服务器谁将从中加载类并将它们呈现给GWT服务器

答案 1 :(得分:3)

在Java 7 URLClassLoader中有一个#close()方法可以修复此问题。