当前位置:  开发笔记 > 编程语言 > 正文

在java中卸载类?

如何解决《在java中卸载类?》经验,为你挑选了5个好方法。

我有一个自定义类加载器,以便桌面应用程序可以动态地从我需要与之交谈的AppServer加载类.我们之所以这样做是因为要做这件事所需的罐子数量是荒谬的(如果我们想要运送它们).如果我们不在运行时从AppServer库动态加载类,我们也会遇到版本问题.

现在,我遇到了一个问题,我需要与两个不同的AppServer交谈,并发现根据我首先加载的类我可能会破坏...有没有办法强制卸载类而不实际杀死JVM?

希望这是有道理的



1> Mario Ortegó..:

可以卸载Class的唯一方法是使用的Classloader是垃圾回收.这意味着,对每个类和类加载器本身的引用都需要采用渡渡鸟的方式.

解决问题的一种可能方法是为每个jar文件提供一个Classloader,为每个AppServer提供一个Classloader,它将实际的类加载委托给特定的Jar类加载器.这样,您可以为每个App服务器指向不同版本的jar文件.

不过,这不是微不足道的.OSGi平台努力做到这一点,因为每个bundle都有不同的类加载器,并且平台解决了依赖关系.也许一个好的解决方案是看看它.

如果您不想使用OSGI,一种可能的实现可能是为每个JAR文件使用一个JarClassloader类实例.

并创建一个扩展Classloader的新的MultiClassloader类.此类内部将具有JarClassloaders的数组(或List),并且在defineClass()方法中将遍历所有内部类加载器,直到找到定义或抛出NoClassDefFoundException.可以提供几种访问器方法来向类中添加新的JarClassloaders.对于MultiClassLoader,网上有几种可能的实现方式,因此您甚至可能不需要编写自己的实现.

如果为服务器的每个连接实例化一个MultiClassloader,原则上每个服务器可能使用同一个类的不同版本.

我在一个项目中使用了MultiClassloader的想法,其中包含用户定义脚本的类必须从内存中加载和卸载,并且它运行良好.


另请注意,根据http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html,卸载类是一种优化,并且根据JVM的实现,可能会或可能不会实际发生.
作为OSGi的一个简单而轻量级的替代品,请尝试[JBoss Modules](https://docs.jboss.org/author/display/MODULES/Home) - 每个模块(一组jar)使用classloader进行模块化类加载.

2> Georgi..:

是的,有些方法可以加载类并在以后"卸载"它们.诀窍是实现自己的类加载器,它位于高级类加载器(System类加载器)和应用服务器的类加载器之间,并希望应用服务器的类加载器将类加载委托给上层加载器. .

类由其包,名称和最初加载的类加载器定义.编写一个"代理"类加载器,它是第一个在启动JVM时加载的类加载器.工作流程:

程序启动,真正的"main"类由此代理类加载器加载.

然后,通常加载的每个类(即不通过可能破坏层次结构的另一个类加载器实现)将被委托给此类加载器.

代理类加载器的代表java.x,并sun.x在系统类加载器(这些不得通过任何其他的类加载器不是系统类加载器加载).

对于每个可替换的类,实例化一个类加载器(它真正加载类并且不将它委托给父类加载器)并通过它加载它.

将类的包/名称作为键存储,并将类加载器作为值存储在数据结构中(即Hashmap).

每次代理类加载器获取之前加载的类的请求时,它都会从之前存储的类加载器返回该类.

应该足以通过类加载器定位类的字节数组(或者从数据结构中"删除"键/值对)并重新加载类以防您想要更改它.

做完就不应该出现ClassCastException或LinkageError等.

有关类加载器层次结构的更多信息(是的,这正是您在此处实现的内容; - )请参阅Ted Neward的"基于服务器的Java编程" - 该书帮助我实现了与您想要的非常相似的内容.


我不理解那些在没有发表评论的情况下为这个答案打勾-1的人.对我来说看起来不错.也许每个类有一个`ClassLoader`有点太多,每个JAR一个`ClassLoader`是有意义的.可以更具体地说明如何在提议的架构中强制上传类?例如,我怎么能保证ClassLoaderB加载的类的实例不被ClassLoaderB加载的实例引用?

3> Kamran..:

我编写了一个自定义类加载器,从中可以卸载单个类而无需GCing类加载器.Jar类加载器



4> Steve g..:

类加载器可能是一个棘手的问题.如果您使用多个类加载器并且没有明确和严格定义其交互,则尤其会遇到问题.我认为为了实际上能够卸载一个类,你必须删除对你试图卸载的任何类(及其实例)的所有引用.

大多数需要做这种事情的人最终都会使用OSGi.OSGi功能强大,重量轻,易于使用,



5> Jason Cohen..:

您可以卸载ClassLoader,但不能卸载特定的类.更具体地说,您无法卸载在不受您控制的ClassLoader中创建的类.

如果可能的话,我建议您使用自己的ClassLoader,以便卸载.

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有