How to unload Java Class Come scaricare classe Java
I have been asked this question several times. Mi è stato chiesto a questa domanda più volte. Recently Xyling asked the same question in his blog. Xyling recentemente la stessa domanda nel suo blog. So I thought a simple explanation may be in order. Così ho pensato una semplice spiegazione può essere in ordine.
To unload a class you have to create a custom classloader and load the class using it. Per scaricare una classe si deve creare un classloader personalizzato e caricare la classe di utilizzarlo. Tomcat does it and so does JRun. Tomcat e lo fa in modo non JRun. You can look in Tomcat code for an example. È possibile osservare in Tomcat codice per un esempio.
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. Dopo aver finito con la classe è necessario liberare tutti i riferimenti alla classe e alla classe del caricatore di riassegnazione delle variabili o di regolazione a nulla.
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. Poi o attendere System.gc () per scaricare la classe o di chiamare direttamente in un ciclo fino a più byte non possano essere liberati. however normally calling it twice does the trick. tuttavia normalmente chiamata due volte il trucco.
Note: You cannot unload a single class. Nota: non è possibile scaricare una singola classe. You have to unload the classloader along with it. Dovete scaricare il classloader con essa. So obviously System classloader is not the suitable for this task. Così, ovviamente, classloader di sistema non è adatto per questo compito.
Note 2: This is how JSP pages are reloaded dynamically everytime you change the code. Nota 2: Questo è il modo in pagine JSP sono ricaricati dinamicamente ogni volta che modifichi il codice. And yes that is why first time takes much longer to load then subsequent times. E sì che è il motivo per cui prima volta richiede molto più tempo per caricare poi le successive volte.
Filed under Elencato sotto How To Come , Java Software Software Java , Technology Tecnologia | |
| |
RSS 2.0 RSS 2,0 | |
Email this Article Invia questo articolo
You may also like to read Si può anche leggere come |




March 15th, 2005 at 6:31 pm 15 marzo 2005 a 6:31 pm
Hi, Salve,
Thank you very much for this information. La ringrazio molto per queste informazioni.
Mind if I extend my question here itself? Mente se Rivolgo qui la mia domanda? Actually, I load my classes through URLClassLoader. In realtà, io il mio carico classi attraverso URLClassLoader. And generally I am loading JAR files through URLClassLoader. E generalmente sono di carico attraverso il file JAR URLClassLoader. Now I want this JAR file to be unloaded. Ora voglio questo file JAR per essere scaricati. Can I extend your logic to URLClassLoader for JAR files too? Posso estendere la vostra logica di URLClassLoader per file JAR troppo?
March 15th, 2005 at 6:33 pm 15 marzo 2005 a 6:33 pm
Thank you. Grazie.
March 15th, 2005 at 6:41 pm 15 marzo 2005 a 6:41 pm
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 ;-). In realtà, le JSP primo tempo di caricamento non è solo a causa della classe essere ricaricati, (il caricamento di una classe dal bytecode non tiene a lungo che, se ha fatto Java sarebbe molto più lenta di quanto lo sia ;-). 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. Un più significativo periodo di tempo è trascorso la generazione del bytecode, come la modifica della fonte JSP deve essere convertito in prima sorgente Java, e poi in a byte-code, che poi può essere caricato dal ClassLoader. So, add two parse/generate cycles to one byte load… Quindi, aggiungere due parsing / a generare cicli di carico di un byte…
March 16th, 2005 at 4:28 pm Marzo 16, 2005 at 4:28 pm
If you are interested in seeing an interesting twist on dynamic reloading of classes, check out the source in our plugin engine at Se siete interessati a vedere un interessante torcere a dinamica di ricarico delle classi, controlla la fonte nel nostro motore al plug in 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. Noi non solo caricare i collegamenti, ciascuno con le proprie classi, ma ora stiamo aggiungendo la possibilità di scaricare dinamicamente porzioni di un plugin che dipendono da un altro.
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. Come si scopre, quando un plug fornisce un'interfaccia plug B che prevede l'attuazione di uno, il plugin B ClassLoader (attraverso la delega a un classloader's) in possesso di una serratura, concernente l'applicazione della classe stessa. 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. Anche dopo che il null classloader plug in A (se stiamo cercando di scaricare A), B's classloader mantiene un blocco su A, perché l'interfaccia di classe B che l'attuazione della classe mantiene un lucchetto. Basically you have this: In pratica dovete:
interface pluginAInterface{} interfaccia pluginAInterface ()
class pluginBImpl implements pluginAInterface{} pluginBImpl classe implementa pluginAInterface ()
each is loaded by a different classloader. ciascuno è caricato da un diverso classloader. When used, plugin B’s classloader sees that pluginBImpl implements pluginAInterface. Quando viene utilizzato, plug in B's classloader pluginBImpl vede che implementa pluginAInterface. It starts in plugin B’s classloader looking for it. Inizia nel plug B's classloader cercando. It can’t find it there (because the pluginAInterface Class is in plugin A’s classloader classpath). Essa non può trovare qui (perché il pluginAInterface è in Classe A plug classloader classpath). The plugin engine delegates the lookup to plugin A’s classloader to find the byte code for this pluginAInterface Class. Il plugin delegati il motore di ricerca di plug A classloader per trovare il codice di byte per questo pluginAInterface Class. 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. È trovato lì, in modo plug A classloader "carichi" il bytecode, ma plug B's classloader "vede" il bytecode di delega inizialmente in A per trovarlo. 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. Una volta trovato, un classloader incorporato nella cache memorizza le classi: la classe puntatore (significato, il classloader e la classe costituiscono una sorta di "chiave" come un puntatore a effettivo bytecode in memoria) in modo che non ha più bisogno di delegare a A. Ma il grosso problema è che la classe pluginBImpl mantiene il proprio elenco di interfacce che implementa, in primo luogo la loro classe di riferimento. The bad thing about this is there is no way to set this to null at runtime! La cosa negativa è su questo non c'è modo di impostare questo valore a null a runtime!
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. In modo che i nostri trucco è quello di utilizzare un secondo classloader entro un plugin di permettere a ciascuno di interfaccia attuate da un altro plug in per avere un suo classloader in modo da scartare che un ricarico per arrivare / scarico al lavoro.
It’sa bit tricky, but it does the trick. È un po 'complicato, ma il trucco. Probably still more hidden issues we haven’t come across yet. Probabilmente ancora più nascosto questioni che non hanno ancora venire attraverso.
March 18th, 2005 at 3:00 am 18 marzo 2005 a 3:00 am
@Goldy Lukka Yes. @ Goldy Lukka Sì. You should be able to. Si dovrebbe essere in grado di farlo. However I haven’t used URLClassLoader in this fashion, so I am not sure if it has any hard-to-remove references. Tuttavia io non ho utilizzato URLClassLoader in questo modo, quindi non sono sicuro se ha qualsiasi difficili da rimuovere i riferimenti. I guess a spike solution is in order Immagino un picco soluzione è per
BTW: I enjoy your site. BTW: Mi piace il tuo sito.
@Kevin Thanks for the very informative comment. Kevin @ Grazie per il commento molto informativo.
March 19th, 2005 at 2:54 am 19 marzo 2005 a 2:54 am
Goldy Lukka, Goldy 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. Il trucco di utilizzare URLClassLoader per ricaricare o scaricare. File jar è fare in modo che nessun altro codice di riferimento a una qualsiasi delle classi entro il. Jar file. Dependencies are difficult to manage. Dipendenze sono difficili da gestire. We have gone to great pains to try to resolve unload/reload with the issue of plugins depending on one another. Siamo andati a grandi dolori per tentare di risolvere scaricare / a ricaricare la questione dei collegamenti a seconda l'un l'altro. We still have problems in many cases making it happen. Abbiamo ancora problemi, in molti casi, rendendo accadere. 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. In alcuni casi, gli sviluppatori di plugin solo devono essere consapevoli del fatto che, se vogliono fare i loro plug come dinamica del possibile, essi hanno veramente a sviluppare in modo tale che esse correttamente ripulire i riferimenti sono a plug in altri classi.
If your .jar file is just adding implementations to say, a core applications interface API, you should be able to easily remove it. Se il tuo. Barattolo file è solo l'aggiunta di implementazioni di dire, un nucleo di interfaccia API di applicazioni, si dovrebbe essere in grado di rimuovere facilmente. As we discovered, an implemting class keeps a reference (lock) on the interface it implements. Come abbiamo scoperto, un implemting classe mantiene un riferimento (blocco) sulla interfaccia essa svolte. 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. Così la classe nel file. Jar file potrebbe mantenere il rif alla interfaccia, che è andato bene, si è semplicemente nullo e / o nullo il classloader che il caricato. Vaso e siete bene. If however the .jar file provides interfaces that other classes (maybe from other .jar files) make use of, that becomes more difficult. Se tuttavia il. Barattolo file fornisce interfacce che altre classi (forse da altri. File jar) utilizzare, che diventa più difficile. 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. Ogni classe al di fuori del classloader che il caricato. Barattolo di file che si avvalgono di ogni classe da dentro il caricato. Vaso deve anche essere scaricati. Again, referring to our engine, it starts a chain reaction of unloading events that can be difficult to manage. Ancora una volta, facendo riferimento al nostro motore, inizia una reazione a catena di scarico eventi che possono essere difficili da gestire. We solved the problem by having two classloader instances per plugin. Abbiamo risolto il problema di avere due casi per classloader plugin. One that handles the interfaces that are implemented by other plugin classes, and one for the rest of the classes. Uno che si occupa di gestire le interfacce che sono attuate da altri plug in classi, e una per il resto della classe. It’s not pretty, but thus far it works. Non è bello, ma finora funziona. We are still experimenting to make this a better process. Stiamo ancora sperimentando per rendere questo un migliore processo.
March 22nd, 2005 at 7:35 pm 22 marzo 2005 a 7:35 pm
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: E 'vero che non si può nulla il riferimento alla interfaccia di classe (Classe # getInterfaces ()), se questo è stato possibile, significherebbe che si rimuove l'interfaccia del codice di byte in fase di esecuzione, da:
public class MyTestImpl implements TestImpl classe pubblica MyTestImpl implementa TestImpl
{ (
} )
to a
public class MyTestImpl classe pubblica MyTestImpl
{ (
} )
The same is true for superclasses. Lo stesso vale per superclasses.
March 23rd, 2005 at 6:23 pm Marzo 23, 2005 at 6:23 pm
it’s great information that how plugins are works. it's great informazioni che come plugin sono opere. Can i have the simplest possible code of custom class loader. Posso avere il più semplice possibile personalizzato codice di classe loader. Ultimately the custom class loader is nees to be loaded by the default classloader or not? In ultima analisi, l'usanza di classe caricatore è nees per essere caricato di default classloader o no? If so then will i be able to see to classloader in the callgraph of such kind of program? Se è così allora sarò in grado di vedere al classloader nel callgraph di tale tipo di programma?
April 1st, 2005 at 6:02 am 1 ° aprile 2005 a 6:02 am
@Sandip Why not use the URLClassLoader? @ Sandip Perché non utilizzare il URLClassLoader? Also there is a sample ClassLoader code provided in Java Tutorials. Inoltre vi è un esempio di codice fornito ClassLoader in Java Tutorial.
September 11th, 2006 at 11:39 am 11 settembre 2006 alle 11:39
Thanks for the information. Grazie per le informazioni.
I read something on the internet which I think is important for some people here: Ho letto qualcosa su Internet che credo sia importante per alcune persone qui:
Two classes are not of the same package if they are loaded by different ClassLoader objects! Due classi non sono dello stesso pacchetto se sono caricati di diversi oggetti ClassLoader!
Let’s say you have a package with two classes, one is public and the other package-private. Diciamo che hai un pacchetto con due classi, è uno pubblico e l'altro pacchetto-privato. These should be loaded by the same ClassLoader(or subclass) object. Queste devono essere caricati dallo stesso ClassLoader (o sottoclasse) oggetto. If you don’t you get a runtime error when the public class tries to access the package-private class. Se non si ottiene un errore di runtime quando la classe pubblica tenta di accedere al pacchetto-privato classe.
So if you planned to make a new ClassLoader object for every class, consider using one ClassLoader object for each package. Quindi, se avete in programma di fare un nuovo oggetto ClassLoader per ogni classe, si consideri l'utilizzo di uno ClassLoader oggetto per ogni pacchetto. The other option is to make all classes public. L'altra opzione è quella di rendere pubbliche tutte le classi.