How to unload Java Class Cómo descargar la clase de Java
I have been asked this question several times. Me ha formulado esta pregunta en varias ocasiones. Recently Xyling asked the same question in his blog. Recientemente Xyling la misma pregunta en su blog. So I thought a simple explanation may be in order. Así que pensé una simple explicación puede estar en orden.
To unload a class you have to create a custom classloader and load the class using it. Para descargar una clase usted tiene que crear una carga de clases y la clase de usarlo. Tomcat does it and so does JRun. Tomcat lo hace y lo mismo ocurre con JRun. You can look in Tomcat code for an example. Puede buscar en Tomcat código para un ejemplo.
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. Después de que hayas terminado con la clase que necesita poner en libertad a todas las referencias a la clase, así como a la clase cargador de reasignación de las variables o el establecimiento a 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. A continuación, o bien esperar a System.gc () para descargar la clase o llame directamente en un bucle hasta no más bytes puede ser liberado. however normally calling it twice does the trick. Sin embargo, normalmente el doble de llamadas que hace el truco.
Note: You cannot unload a single class. Nota: No se puede descargar una sola clase. You have to unload the classloader along with it. Tienes que descargar el cargador de clases a lo largo de la misma. So obviously System classloader is not the suitable for this task. Así que, obviamente, del sistema de clases no es el adecuado para esta tarea.
Note 2: This is how JSP pages are reloaded dynamically everytime you change the code. Nota 2: Esta es la forma en JSP se recargan las páginas de forma dinámica cada vez que cambies el código. And yes that is why first time takes much longer to load then subsequent times. Y sí que es la razón por la primera vez que toma mucho más tiempo para cargar a continuación, los tiempos posteriores.
Filed under Filed under How To Cómo , Java Software El software de Java , Technology Tecnología | |
| |
RSS 2.0 RSS 2,0 | |
Email this Article Enviar artículo
You may also like to read También puede leer |




March 15th, 2005 at 6:31 pm 15 de marzo de 2005, a las 6:31 pm
Hi, Hola,
Thank you very much for this information. Muchas gracias por esta información.
Mind if I extend my question here itself? Mente si hago llegar mi pregunta aquí? Actually, I load my classes through URLClassLoader. En realidad, me carga a través de mis clases URLClassLoader. And generally I am loading JAR files through URLClassLoader. Y, en general, estoy de carga a través de los archivos JAR URLClassLoader. Now I want this JAR file to be unloaded. Ahora quiero este archivo JAR para ser descargadas. Can I extend your logic to URLClassLoader for JAR files too? ¿Puedo extender su lógica a URLClassLoader para archivos JAR demasiado?
March 15th, 2005 at 6:33 pm 15 de marzo de 2005, a las 6:33 pm
Thank you. Gracias.
March 15th, 2005 at 6:41 pm 15 de marzo de 2005, a las 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 ;-). En realidad, la primera JSP tiempo de carga no se debe únicamente a la clase ser recargadas, (una clase de carga de la bytecode no tiene tanto tiempo, si lo hizo Java sería mucho más lento de lo que es ;-). 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. A más cantidad significativa de tiempo se dedica a la generación de bytecode, como un cambio en la fuente JSP que se ha convertido en primera fuente de Java y, a continuación, a byte-code, lo que puede ser cargado por el cargador de clases. So, add two parse/generate cycles to one byte load… Por lo tanto, añadir dos analizar y generar ciclos de carga un byte…
March 16th, 2005 at 4:28 pm 16 de Marzo, 2005 a las 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 Si usted está interesado en ver un interesante giro a carga dinámica de las clases, echa un vistazo a la fuente de nuestro motor a plugin 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. No sólo carga los plugins, cada una con sus propias clases, pero ahora estamos añadiendo la posibilidad de descargar dinámicamente partes de un plugin que dependen de otro.
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. Como resulta que, cuando un plugin proporciona una interfaz plugin B que proporciona una aplicación para el plugin de clases B (a través de una delegación a la de clases) tiene un bloqueo sobre la aplicación de clase en sí. 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. Incluso después de que fuera nulo el plugin de clases en A (si estamos tratando de descargar A), B de clases del mantiene un bloqueo en una causa de la interfaz que la clase B de la aplicación de clase mantiene un bloqueo en. Basically you have this: En el fondo está esta:
interface pluginAInterface{} interfaz pluginAInterface ()
class pluginBImpl implements pluginAInterface{} pluginBImpl clase implementa pluginAInterface ()
each is loaded by a different classloader. cada uno está cargado de diferentes clases. When used, plugin B’s classloader sees that pluginBImpl implements pluginAInterface. Cuando se usa, B plugin de clases del pluginBImpl ve que implementa pluginAInterface. It starts in plugin B’s classloader looking for it. Comienza en plugin de clases del B en busca de ella. It can’t find it there (because the pluginAInterface Class is in plugin A’s classloader classpath). No puede encontrar allí (pluginAInterface porque la clase está en un plugin de clases del classpath). The plugin engine delegates the lookup to plugin A’s classloader to find the byte code for this pluginAInterface Class. El plugin motor de búsqueda de los delegados a la una del plugin de clases para encontrar el código byte para esta clase 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. Se encuentra allí, para que un plugin de clases del "cargas" el bytecode, pero plugin B de clases del "ve" el bytecode inicialmente por la delegación de la A a encontrarlo. 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 vez encontrados, uno de clases incorporada en la memoria caché almacena las clases: la clase puntero (es decir, las clases y la clase forman una especie de "clave" como un puntero a la real bytecode en la memoria) por lo que ya no tiene que delegar en A. Pero, el gran problema es que la clase pluginBImpl mantiene su propia lista de interfaces que implementa, principalmente su clase de referencia. The bad thing about this is there is no way to set this to null at runtime! La mala cosa sobre esto es que no hay forma de establecer este a null en tiempo de ejecución!
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. Por lo tanto, nuestro truco es utilizar un segundo de clases dentro de un plugin para permitir que cada interfaz ejecutado por otro plugin para tener su propio de clases de modo que podemos descartar que para conseguir una recarga y descarga para trabajar.
It’sa bit tricky, but it does the trick. Es un poco complicado, pero el truco. Probably still more hidden issues we haven’t come across yet. Probablemente todavía más ocultas cuestiones no hemos encontrado aún.
March 18th, 2005 at 3:00 am 18 de marzo de 2005, a las 3:00 am
@Goldy Lukka Yes. @ Goldy Lukka Sí. You should be able to. Usted debe ser capaz de. However I haven’t used URLClassLoader in this fashion, so I am not sure if it has any hard-to-remove references. Sin embargo no he utilizado URLClassLoader de esta manera, por lo que no estoy seguro de si tiene algún difíciles de eliminar referencias. I guess a spike solution is in order Supongo que una espiga solución está en orden
BTW: I enjoy your site. BTW: Me gusta su sitio.
@Kevin Thanks for the very informative comment. @ Kevin Gracias por el comentario muy informativo.
March 19th, 2005 at 2:54 am 19 de marzo del 2005 a las 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. El truco de utilizar URLClassLoader para volver a cargar o descargar. Jar es asegurarse de que ningún otro código de referencias a cualquiera de las clases dentro de la. Jar. Dependencies are difficult to manage. Dependencias son difíciles de gestionar. We have gone to great pains to try to resolve unload/reload with the issue of plugins depending on one another. Hemos ido a grandes esfuerzos para tratar de resolver descarga / recarga con el tema de plugins en función de unos a otros. We still have problems in many cases making it happen. Todavía tenemos problemas en muchos casos hacer que suceda. 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. En algunos casos, los desarrolladores de plugins sólo hay que ser conscientes de que si quieren hacer su plugin tan dinámico como es posible, que realmente tienen que desarrollar de tal manera que limpiar correctamente todas las referencias que tienen en otras clases plugin.
If your .jar file is just adding implementations to say, a core applications interface API, you should be able to easily remove it. Si tu. Archivo jar es simplemente añadir implementaciones decir, un núcleo de las aplicaciones de interfaz API, usted debería ser capaz de eliminar fácilmente. As we discovered, an implemting class keeps a reference (lock) on the interface it implements. Como hemos descubierto, un implemting clase mantiene una referencia (bloqueo) en la interfaz que implementa. 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. Así que la clase en su archivo. Jar mantendría la ref a la interfaz, lo cual es correcto, simplemente es nula y / o nulas las clases que ha cargado el archivo. Frasco y se le multa. If however the .jar file provides interfaces that other classes (maybe from other .jar files) make use of, that becomes more difficult. No obstante, si el. Archivo jar que proporciona interfaces de otras clases (tal vez de otros. Jar) hacer uso de, que se vuelve más difícil. 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. Cualquier clase fuera de las clases que ha cargado el archivo. Jar haciendo uso de toda clase desde el interior de la carga. Frasco tiene que ser también la descarga. Again, referring to our engine, it starts a chain reaction of unloading events that can be difficult to manage. Una vez más, refiriéndose a nuestro motor, inicia una reacción en cadena de acontecimientos que se descarga puede ser difícil de manejar. We solved the problem by having two classloader instances per plugin. Hemos resuelto el problema de tener dos instancias de clases por el plugin. One that handles the interfaces that are implemented by other plugin classes, and one for the rest of the classes. Uno que maneja los interfaces que son ejecutadas por otras clases plugin, y otro para el resto de las clases. It’s not pretty, but thus far it works. No es bonito, pero hasta ahora funciona. We are still experimenting to make this a better process. Estamos todavía experimentando para hacer de este un mejor proceso.
March 22nd, 2005 at 7:35 pm Sábado 22 de marzo de 2005, a las 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: Es cierto que no se puede nula la referencia a la interfaz de clase (clase # getInterfaces ()), si ello era posible que significaría que le quite la interfaz en el código byte en tiempo de ejecución, a partir de:
public class MyTestImpl implements TestImpl MyTestImpl público de clase implementa TestImpl
{ (
} )
to para
public class MyTestImpl clase pública MyTestImpl
{ (
} )
The same is true for superclasses. Lo mismo puede decirse de superclases.
March 23rd, 2005 at 6:23 pm 23 de Marzo, 2005 a las 6:23 pm
it’s great information that how plugins are works. es una gran información que la forma en que los plugins son obras. Can i have the simplest possible code of custom class loader. ¿Puedo tener el código más simple posible de la costumbre clase cargador. Ultimately the custom class loader is nees to be loaded by the default classloader or not? En última instancia, la costumbre es la clase cargador Nees que se cargan por defecto de clases o no? If so then will i be able to see to classloader in the callgraph of such kind of program? Si es así entonces voy a ser capaz de ver a clases en la callgraph de este tipo de programa?
April 1st, 2005 at 6:02 am 1 de abril de 2005, a las 6:02 am
@Sandip Why not use the URLClassLoader? @ Sandip ¿Por qué no utilizar el URLClassLoader? Also there is a sample ClassLoader code provided in Java Tutorials. También hay una muestra de clases previstas en el código Java Tutoriales.
September 11th, 2006 at 11:39 am 11 de septiembre de 2006, a las 11:39 am
Thanks for the information. Gracias por la información.
I read something on the internet which I think is important for some people here: He leído algo en internet que creo que es importante para algunas personas aquí:
Two classes are not of the same package if they are loaded by different ClassLoader objects! Dos clases no son del mismo paquete, si se cargan las diferentes clases de objetos!
Let’s say you have a package with two classes, one is public and the other package-private. Digamos que usted tiene un paquete con dos clases, una es pública y el otro paquete y el privado. These should be loaded by the same ClassLoader(or subclass) object. Estos deben ser cargados por las mismas clases (o subclase) objetos. If you don’t you get a runtime error when the public class tries to access the package-private class. Si no obtiene un error en tiempo de ejecución cuando el público de clase intenta acceder al conjunto de la clase y el privado.
So if you planned to make a new ClassLoader object for every class, consider using one ClassLoader object for each package. Por lo tanto, si tiene previsto hacer un nuevo objeto de clases para cada clase, considere la posibilidad de utilizar un objeto de clases para cada paquete. The other option is to make all classes public. La otra opción es hacer que todas las clases públicas.