如何卸载Java类
Angsuman Chakraborty
2005年3月15日
我被请求这个问题多次。 最近Xyling问在他的博客的同一个问题。 因此我认为一个简单的解释也许按顺序。
使用它,要卸载类您必须创造一习惯classloader和装载类。 雄猫做它和,因此做JRun。 您在雄猫代码能看为例子。
在您做与类之后您需要发布在类的所有参考并且给类装载者通过再分配可变物或设置他们使无效。
然后等待System.gc ()卸载类或您电话它直接地在圈,没有其他字节不可以被释放。 通常叫它两次获得成功。
注: 您不可能卸载唯一类。 您必须与它一起卸载classloader。 那么明显地系统classloader不适用于这项任务。
笔记2 : 这是JSP页怎么动态地每次被再装您变动代码。 并且是所以第一次花费很多时间然后装载随后时期。
归档在 怎么之下对, Java软件, 技术 |
|
RSS 2.0 |
给这篇文章发电子邮件
您可以也喜欢读 |


增加到Technorati喜爱

































2005年3月15日在6:31 pm
喂,
谢谢对于这信息。
如果我扩大我的问题这里本身,介意? 实际上,我通过URLClassLoader装载我的类。 并且通常我是装货瓶子文件通过URLClassLoader。 现在我要这个瓶子文件被卸载。 我可以对瓶子文件的URLClassLoader也是扩大您的逻辑?
2005年3月15日在6:33 pm
谢谢。
2005年3月15日在6:41 pm
实际上, JSP一装载时间不仅归结于被再装的类, (装载类从bytecode不花费那很多时间,如果它比它做了Java很慢; -)。 花费引起bytecode的更加重大的时间,当对JSP来源的变动必须被转换首先成Java来源,然后字节代码,可能由ClassLoader然后装载。 因此,加二解析或引起周期对一字节装载…
2005年3月16日在4:28 pm
如果您是对看在动态再装的有趣的转弯感兴趣类,检查在我们的插入式引擎的来源在 http://www.platonos.org。 我们不仅装载插入,中的每一与他们自己的classloader,但是我们现在增加能力动态地卸载依靠别的部分的插入式。
结果是,当插入式A提供一个接口时插入式B提供实施为,插入式B ClassLoader (通过A的classloader的代表团)拿着在实施类的一把锁。 在我们以后使在插入式A的classloader无效(如果我们设法卸载A), B的classloader保留在A的一把锁由于接口类B的实施类保留一把锁。 基本上您有此:
接口pluginAInterface {}
类pluginBImpl实施pluginAInterface {}
其中每一由一不同的classloader装载。 当使用,插入式B的classloader看那pluginBImpl贯彻pluginAInterface。 它在寻找它的插入式B的classloader开始。 (因为pluginAInterface类在插入式A的classloader classpath),它找不到它那里。 插入式引擎委派查寻对插入式A的classloader发现这pluginAInterface类的字节代码。 它找到得那里,因此插入式A的classloader “装载” bytecode,但是插入式B的classloader “通过对A发现它的最初委派看” bytecode。 一次找到,在高速缓冲存储器建立的classloader的classloader :类尖(意思、classloader和类组成一种“钥匙”作为尖对在记忆的实际bytecode),因此不再需要委派到A.,但是,大问题是pluginBImpl类维护它是拥有它实施接口的名单,主要他们的类参考。 关于此的坏事是没有办法设置此使无效在运行时间!
因此我们的把戏是使用在插入式之内的第二classloader允许别的实施的每个接口插入式有它是拥有classloader,因此我们可以放弃那一个得到再装或卸载工作。
它是棘手的,但是它获得成功。 大概仍然暗藏的问题我们未遇到。
2005年3月18日在3:00上午
是@Goldy Lukka。 您应该能。 然而我用这种方式未使用URLClassLoader,因此我不是肯定的,如果它安排其中任一坚硬对去除参考。 我猜测钉解答按顺序
BTW : 我享用您的站点。
@Kevin感谢非常情报评论。
2005年3月19日在2:54上午
Goldy Lukka,
对使用URLClassLoader的把戏再装或卸载.jar文件保证其他代码不参考其中任一在.jar文件之内的类。 附庸是难处理。 我们去巨大痛苦设法解决卸载或再装与插入的问题依靠互相。 我们在许多情况下仍然安排问题做它发生。 有时,插入的开发商必须知道,如果他们想要做他们插入式一样动态尽可能,他们必须真正地开发它,在这种情况下他们适当地清扫所有参考他们有在其他插入式类。
如果您的.jar文件增加实施说,核心应用连接API,您应该能容易地去除它。 如同我们发现了, implemting的类保留它实施的参考(锁)在接口。 因此在您的.jar文件的类将保留对接口的ref是好的,您使它无效并且/或者使装载.jar的classloader无效,并且您优良是。 然而如果.jar文件提供其他类的接口(可能从其他.jar文件)利用,那变得更加困难。 任何类在装载利用任何类的.jar文件从被装载的.jar里边的classloader外面必须也被卸载。 再次,提到我们的引擎,它开始卸载可以是难处理的事件一个链式反应。 我们由有解决了问题每插入式的二个classloader事例。 处理接口由其他插入式类实施的一和一个类的其余的。 它不是俏丽的,但是它至今运作。 我们仍然试验做这一个更好的过程。
2005年3月22日在7:35 pm
凯文,
是真实的您不可能使在接口类(Class#getInterfaces的参考无效()),如果这是可能的意味您去除在字节代码的接口在运行时间,从:
公开类MyTestImpl实施TestImpl
{
}
公开类MyTestImpl
{
}
同样真实对superclasses。
2005年3月23日在6:23 pm
它是的了不起的信息插入怎么是工作。 可以我有习惯类装载者最简单的可能的代码。 最终习惯类装载者是缺省classloader将装载的nees ? 如果那么然后i能看到在这样callgraph的classloader节目?
2005年4月1日在6:02上午
@Sandip为什么不使用URLClassLoader ? 并且有在Java讲解提供的样品ClassLoader代码。
2006年9月11日在11:39上午
感谢对于信息。
我在我认为对某些人民在重要这里的互联网读某事:
如果他们由不同的ClassLoader对象,装载二类不是同一个包裹!
假设您有与二类的一个包裹,一个是公开和包裹私有的其他。 应该由同一个ClassLoader (或子类)对象装载这些。 如果您您没有一个运行错误,当公开类设法访问包裹私有类。
因此,如果您计划做每类的一个新的ClassLoader对象,考虑使用一个ClassLoader对象为每个包裹。 另一个选择是做所有类公众。