« marzo 2010
lunmarmiéjueviesábdom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    
       
Hoy

Publicidad

Creative Commons License 2.0

Technorati Profile

Links

RSS

Blog::Menu

« Comprimiendo WebServ... | Main | Plug and Play, el... »
viernes ene 02, 2009

Carga de clases, classloader y un error raro

Solemos pensar que una vez el classloader carga una clase esta nunca se descarga pero,

hay dos casos en los que si el GC necesita memoria, no descarga una clase que ya esta en memoria:

Si hay una clase instanciada el GC nunca la recoleta.
Si tienes una referencia a un objeto clase dentro de un ClassLoader tampoco.

Desde verano llevo buscando un raro error que se produce cuando una propiedad que esta siempre como true aunque por defecto es false, esta con valor false.

Se producia aleatoriamente sobre todo cuando llevaba bastante tiempo trabajando y con un proceso que generaba 200 000 objetos nuevos.

Imaginarse una clase static ejem que tiene un metodo load que carga un properties, se pone la llamada al load en un init de un servlet, luego en un jsp utiliza clase sejem static que contiene un atributo static que se inicializa accediendo al properties cargado en el servlet.

Esto funciona, pero imaginarse que hace falta memoria y al ser clases con todos los metodos y atributos static, son candidatas a descargarlas. En este caso la clase sejem cojera el valor false, con lo que se producira el error que buscaba.

En este caso la clase ejem, no la podia tocar al ser de otros desarrolladores, una solucion ha sido en la clase sejem creame un objeto static asejem y añadir un constructor que hace lo mismo que el init.

De esta forma me aseguro que la clase sejem nunca se va descargar, y que la propiedad siempre la va a coger con la clase ejem cargada.

Como veis un error raro pero que se puede dar en nuestro uso de servlet y clases static.

Comentarios:

Creo que desde la version 1.4 la JVM es capaz de liberar las clases, así que ya nadie debería pensar que las clases no se liberan.
Una mini-critica: dices "hay dos casos por las que el GC puede liberar una clase", y luego explicas dos razones por las que NO lo hace, queda un poco confuso.

Es uno de los clasicos ejemplos por los que no se recomienda usar variables estáticas, y en entorno web (multiples classloaders) es menos recomendable. Existen diferentes objetos con el ciclo de vida adecuado segun lo que queramos que se mantengan nuestras variables (contexto, sesion, peticion, arbol JNDI del servidor...) pero no se usan por "pereza" y desconocimiento. Sin tener claro el ciclo de vida de las clases, classloaders, servlets, contextos... aparecen errores "misteriosos" que no tienen tanto misterio. Y conste que no lo digo por tí, que ya dices que la clase no la has hecho tú ;). Lo de atributos como estaticos para no tener que pasar parametros es muy típico.

S!

Enviado por GreenEyed en enero 03, 2009 a las 06:21 PM GMT+01:00 #

Efectivamente lo que queria poner es que hay dos casos en los que no los libera.

Por las prisas, realize el post sin releerlo, y sin añador las code, negrita etc y no esta muy fino.

De todas formas, lo que queria es que otros vieran el problema, que para mi era en ese momento lo mas importante, ya que como dices es posible que por pereza o por ahorrarse miles de lineas de codigo y paso de variables alguien comenta el mismo error.

Si te creas una copia estatica del objeto inicializado ya no lo baja.

Enviado por batch4j en enero 05, 2009 a las 08:17 AM GMT+01:00 #

Creo que es desde la version 1.4 que la JVM, el GC, es capaz de liberar las clases, así que ya nadie debería pensar que las clases no se liberan.
Una mini-critica en cuanto a la comprensión del texto. Dices "hay dos casos por las que el GC puede liberar una clase", y luego explicas dos razones por las que NO lo hace, queda un poco confuso.

De todas formas, lo que comentas es uno de los clasicos ejemplos por los que no se recomienda usar variables estáticas. Y usarlas en un entorno web donde hay multiples classloaders es aun menos recomendable. Para eso existen diferentes objetos con el ciclo de vida adecuado segun lo que queramos que se mantengan nuestras variables (contexto, sesion, peticion, arbol JNDI del servidor...) pero en muchos casos no se usan por "pereza" y por desconocimiento.

Claro que luego sin tener claro el ciclo de vida de las clases, los classloaders, los servlets, los contextos... aparecen errores "misteriosos" que no tienen tanto misterio. Y conste que no lo digo por tí que ya dices que la clase no la has hecho tú ;). Pero lo de cascar los atributos como estaticos para no tener que pasar parametros es muy típico :).

S!

Enviado por GreenEyed en enero 18, 2009 a las 04:19 PM GMT+01:00 #

Creo que desde la version 1.4 la JVM es capaz de liberar las clases, así que ya nadie debería pensar que las clases no se liberan.
Una mini-critica: dices "hay dos casos por las que el GC puede liberar una clase", y luego explicas dos razones por las que NO lo hace, queda un poco confuso.

Lo que comentas es uno de los clasicos ejemplos por los que no se recomienda usar variables estáticas, y en entorno web (multiples classloaders) es menos recomendable. Existen diferentes objetos con el ciclo de vida adecuado segun lo que queramos que se mantengan nuestras variables (contexto, sesion, peticion, arbol JNDI del servidor...) pero no se usan por "pereza" y desconocimiento.

Claro que sin tener claro el ciclo de vida de las clases, classloaders, servlets, contextos... aparecen errores "misteriosos" que no tienen tanto misterio. Y conste que no lo digo por tí, que ya dices que la clase no la has hecho tú ;). Lo de atributos como estaticos para no tener que pasar parametros es muy típico.

S!

Enviado por GreenEyed en enero 18, 2009 a las 04:19 PM GMT+01:00 #

Enviar un comentario:
  • Sintaxis HTML: Deshabilitado
Copyright (C) 2006-2008, Batch for the Java TM

Java, J2EE, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc

This blog is not affiliated in any way with Sun Microsystems, Inc.