How to unload Java Class如何卸載Java類
I have been asked this question several times.有人問我這個問題的幾倍。 Recently Xyling asked the same question in his blog.最近xyling提出同樣的問題在他的博客。 So I thought a simple explanation may be in order.所以我認為一個簡單的解釋,可能會在秩序。
To unload a class you have to create a custom classloader and load the class using it.卸下一類,你必須創建一個用戶自定義的類和負載的階級使用它。 Tomcat does it and so does JRun.雄貓是否和那麼jrun 。 You can look in Tomcat code for an example.你可以看看在Tomcat代碼的一個例子。
After you are done with the class you need to release all references to the class as well as to the class loader by reassigning the variables or setting them to null.之後,你所做的與一流的,你需要釋放所有的提述,階級以及為類加載器指派的變量或設置他們為NULL 。
Then either wait for System.gc() to unload the class or you call it directly in a loop till no more bytes can be freed.然後等待system.gc ( )卸下階級或您呼叫它直接在循環中,直至沒有更多的字節可以被釋放。 however normally calling it twice does the trick.不過,通常稱它的兩倍是否伎倆。
Note: You cannot unload a single class.注意:您無法卸載一個單一的階級。 You have to unload the classloader along with it.你必須卸下類隨著它。 So obviously System classloader is not the suitable for this task.因此,系統類,顯然是不適合這項工作。
Note 2: This is how JSP pages are reloaded dynamically everytime you change the code.注2 :這是如何JSP頁面是重裝上陣動態每次您變更代碼。 And yes that is why first time takes much longer to load then subsequent times.是的這就是為什麼第一次需要的時間要長得多的負載,然後以後的時代。
Filed under提起下 How To如何 , , Java Software Java軟件 , , Technology技術 | |
| |
RSS 2.0 2.0 | |
Email this Article電子郵件此文章
You may also like to read您也可以想讀 |





March 15th, 2005 at 6:31 pm 2005年3月15日在下午6時31分
Hi,嗨,
Thank you very much for this information.非常感謝你為這方面的資料。
Mind if I extend my question here itself?考慮到如果我延長我的問題在這裡本身呢? Actually, I load my classes through URLClassLoader.其實,我負荷我的班,通過urlclassloader 。 And generally I am loading JAR files through URLClassLoader.和一般我加載jar文件通過urlclassloader 。 Now I want this JAR file to be unloaded.現在我想這個JAR文件,以卸載。 Can I extend your logic to URLClassLoader for JAR files too?我可以延長你的邏輯來urlclassloader為jar文件呢?
March 15th, 2005 at 6:33 pm 2005年3月15日在下午6時33分
Thank you.謝謝您。
March 15th, 2005 at 6:41 pm 2005年3月15日在下午6時41分
Actually, the JSP first-load time is not ONLY due to the class being reloaded, (loading a class from the bytecode doesn’t take that long, if it did Java would be a lot slower than it is ;-).其實, JSP的首次載入時間不僅是由於階級正在重裝上陣, (裝載一類從字節並不需時這麼久,如果沒有Java的將是一個慢很多,這是;-) 。 A more significant amount of time is spent generating the bytecode, as a change to the JSP source has to be converted first into Java source, and then in to byte-code, which can then be loaded by the ClassLoader.更耗費大量的時間是用於生成字節,作為一個改變JSP的來源要轉換的第一到Java源,然後在以字節代碼,然後可以載入由類。 So, add two parse/generate cycles to one byte load…因此,添加兩個解析/生成週期,以一個字節的負載…
March 16th, 2005 at 4:28 pm 2005年3月16日在下午4時28分
If you are interested in seeing an interesting twist on dynamic reloading of classes, check out the source in our plugin engine at如果您有興趣,在看到一個有趣的扭曲的動態加載的班級,請參閱源在我們的插件引擎 http://www.platonos.org . 。 We not only load plugins, each with their own classloader, but we are now adding the ability to dynamically unload portions of a plugin that are dependent on another.我們不僅負荷插件,每一個都有自己的類,但我們現在加入的能力,動態地卸下部分一插件是依賴於另一個。
As it turns out, when plugin A provides an interface that plugin B provides an implementation for, the plugin B ClassLoader (through delegation to A’s classloader) holds a lock on the implementation Class itself.作為原來,當插件一提供了一個界面,插件B提供一實施,插件b類(通過代表團到的類)持有的鎖,執行階層本身。 Even after we null out the classloader in plugin A (if we are trying to unload A), B’s classloader keeps a lock on A because of the interface Class that B’s implementation class keeps a lock on.即使在我們空出的類在插件(如果我們正試圖卸下一) , B的類不斷的鎖1 ,因為該接口類, B的執行階層不斷的鎖。 Basically you have this:基本上你有這:
interface pluginAInterface{}接口pluginainterface ( )
class pluginBImpl implements pluginAInterface{}一流的pluginbimpl實施pluginainterface ( )
each is loaded by a different classloader.每個加載由不同的類。 When used, plugin B’s classloader sees that pluginBImpl implements pluginAInterface.在使用時,插件B的類看到pluginbimpl實施pluginainterface 。 It starts in plugin B’s classloader looking for it.它開始在插件B的類尋找它。 It can’t find it there (because the pluginAInterface Class is in plugin A’s classloader classpath).無法找到它存在(因為pluginainterface工人階級是在插入式的類類) 。 The plugin engine delegates the lookup to plugin A’s classloader to find the byte code for this pluginAInterface Class.插件引擎代表查找到插件A的類找到字節碼為這pluginainterface階層。 It’s found there, so plugin A’s classloader “loads” the bytecode, but plugin B’s classloader “sees” the bytecode by initially delegating to A to find it.它的發現,因此插件A的類“載入”字節,但插件B的類“ ,認為”字節由最初下放給找到它。 Once found, a classloader’s built in cache stores the classloader:class pointer (meaning, the classloader AND the class make up a sort of “key” as a pointer to the actual bytecode in memory) so it no longer needs to delegate to A. BUT, the big problem is that the pluginBImpl Class maintains it’s own list of interfaces it implements, primarily their Class reference.一旦發現,一類的內置高速緩存中存儲類:一流的指針(即,類和階級彌補一種“鑰匙”作為一個指針,以實際字節記憶體中) ,所以不再需要代表答:但是,大問題是該pluginbimpl階層保持它自己的名單,接口實施,主要是他們的階級參考。 The bad thing about this is there is no way to set this to null at runtime!壞的事情,這是是沒有出路的要設置此為null在運行時!
So our trick is to use a second classloader within a plugin to allow each interface implemented by another plugin to have it’s own classloader so we can discard that one to get reloading/unloading to work.因此,我們的伎倆是使用第二類一個插件,讓每個接口實施的另一個插件有它自己的類,所以我們可以拋棄一個獲得加載/卸載工作。
It’sa bit tricky, but it does the trick.這有點棘手,但它確實的把戲。 Probably still more hidden issues we haven’t come across yet.可能仍然隱藏的問題我們還沒有碰到。
March 18th, 2005 at 3:00 am 2005年3月18日在上午03點
@Goldy Lukka Yes. @金黃lukka肯定的。 You should be able to.您應該可以。 However I haven’t used URLClassLoader in this fashion, so I am not sure if it has any hard-to-remove references.不過,我沒有用urlclassloader在這時尚,所以我不知道是否有任何努力,到刪除的提述。 I guess a spike solution is in order我猜想一穗的解決辦法是在命令
BTW: I enjoy your site.的BTW :我喜歡您的網站。
@Kevin Thanks for the very informative comment. @凱文感謝為非常翔實的評論。
March 19th, 2005 at 2:54 am 2005年3月19日在上午02時54分
Goldy Lukka,金黃lukka ,
The trick to using URLClassLoader to reload or unload .jar files is making sure that NO other code is referencing any of the classes within the .jar file.伎倆使用urlclassloader重新載入或卸載。 jar文件是確保沒有其他的代碼是參照任何階級內部。 JAR文件。 Dependencies are difficult to manage.相依是難以管理。 We have gone to great pains to try to resolve unload/reload with the issue of plugins depending on one another.我們已經歷了很大的痛苦,來嘗試解決卸載/重新加載與問題插件,視乎1 。 We still have problems in many cases making it happen.我們仍然有問題,在許多情況下,使情況發生。 In some cases, developers of plugins just have to be aware that if they want to make their plugin as dynamic as possible, they really have to develop it in such a way that they properly clean up any references they have on other plugin classes.在某些情況下,開發商的插件只是要知道,如果他們想使他們的插件作為動態,盡可能他們真的有發展,它在這樣一種方式,他們妥善清理的任何參考,他們對其他插件班。
If your .jar file is just adding implementations to say, a core applications interface API, you should be able to easily remove it.如果您的。 JAR文件是剛剛加入的實現,也就是說,一個核心應用程序接口API ,您應該能夠很容易將它移除。 As we discovered, an implemting class keeps a reference (lock) on the interface it implements.我們發現,一implemting階層不斷參考(鎖)對接口它實現。 So the class in your .jar file would keep the ref to the interface, which is ok, you simply null it out and/or null the classloader that loaded the .jar and you are fine.因此,工人階級在您的。 JAR文件將繼續參到界面,這是確定,您只需將空出來,和/或空的類裝貨。 JAR和您的罰款。 If however the .jar file provides interfaces that other classes (maybe from other .jar files) make use of, that becomes more difficult.然而,如果。 JAR文件提供了接口,其他類別(也許從其他。 JAR文件)使用,即變得更加困難。 Any class outside of the classloader that loaded the .jar file making use of any class from inside the loaded .jar has to also be unloaded.任何一類以外的類裝貨。 JAR文件利用任何一類由內裝貨。瓦罐也已卸下。 Again, referring to our engine, it starts a chain reaction of unloading events that can be difficult to manage.再次,是指我們的引擎,它啟動一個連鎖反應,卸貨的事件,可能難以管理。 We solved the problem by having two classloader instances per plugin.我們解決了這個問題由有兩個類的實例%插件。 One that handles the interfaces that are implemented by other plugin classes, and one for the rest of the classes.一到處理界面,是實施其他插件班,一為其餘的班級。 It’s not pretty, but thus far it works.它的不漂亮,但迄今為止,它的工程。 We are still experimenting to make this a better process.我們仍在試驗,使這是一個更好的進程。
March 22nd, 2005 at 7:35 pm 2005年3月22日在下午7點35分
Kevin,凱文
It’s true that you can’t null the reference to the interface class ( Class#getInterfaces() ), if this was possible it would mean that you remove the interface in the byte code at runtime, from:它的真實,您不能空提述的接口類(級# getinterfaces ( ) ) ,如果這是可能的,這將意味著您移除界面,在字節代碼在運行時,來自:
public class MyTestImpl implements TestImpl公共類mytestimpl實施testimpl
{ (
} )
to至
public class MyTestImpl公共類mytestimpl
{ (
} )
The same is true for superclasses.也是一樣, superclasses 。
March 23rd, 2005 at 6:23 pm 2005年3月23日在下午6時23分
it’s great information that how plugins are works.它的偉大的信息如何插件工程。 Can i have the simplest possible code of custom class loader.我可以有最簡單的代碼自定義類加載器。 Ultimately the custom class loader is nees to be loaded by the default classloader or not?最終自定義類加載器是nees被載入默認的類或不? If so then will i be able to see to classloader in the callgraph of such kind of program?如果是的話,然後,我將能夠看到,以類,在callgraph這類計劃?
April 1st, 2005 at 6:02 am 2005年4月1日在上午06時02分
@Sandip Why not use the URLClassLoader? @ sandip為什麼不使用urlclassloader ? Also there is a sample ClassLoader code provided in Java Tutorials.也有一個樣本的類提供的代碼在Java教程。
September 11th, 2006 at 11:39 am 2006年9月11日在上午11時39分
Thanks for the information.感謝信息。
I read something on the internet which I think is important for some people here:我看過一些在互聯網上,我認為是很重要的,有些人在這裡:
Two classes are not of the same package if they are loaded by different ClassLoader objects!兩班是不是相同的包,如果他們是由不同的加載的類的對象!
Let’s say you have a package with two classes, one is public and the other package-private.讓我們說你有一個方案,與兩班,一個是市民和其他包私人。 These should be loaded by the same ClassLoader(or subclass) object.這些措施應載入由同一類(或子類)對象。 If you don’t you get a runtime error when the public class tries to access the package-private class.如果您不您會獲得一個運行時錯誤時,市民階層的嘗試存取包私人階層。
So if you planned to make a new ClassLoader object for every class, consider using one ClassLoader object for each package.因此,如果您計劃作出新的類對象的每個班級,可以考慮使用一類對象為每個軟件包。 The other option is to make all classes public.另一種選擇是使各階層的市民。