2010-02-26 13 views
38

Estamos creando múltiples cargadores de clase para cargar múltiples subaplicaciones en un "contenedor" de aplicaciones Java, creando prototipos de implementación en caliente. Cuando la classpath de un cargador de clases particular ha cambiado (es decir, se han agregado, eliminado, actualizado), el antiguo cargador de clases se descarta (no referenciado) y se crea un nuevo cargador de clases para el nuevo classpath de jar.¿Cuándo y cómo se marca un cargador de clases java para la recolección de basura?

Después de actualizar el classpath, desencadenando el despliegue activo, tomamos un volcado de pila. El volcado de pila (con Memory Analyzer) indica que los cargadores de clase antiguos no se estaban recogiendo basura. Ciertas clases en el cargador de clases padre almacenaban en caché los antiguos cargadores de clases. Las siguientes cosas se han invocado para despejar estas cachés:

java.lang.ResourceBundle.clearCache(classLoader); 
org.apache.commons.logging.LogFactory.release(classLoader); 
java.beans.Introspector.flushCaches(); 

Incluso después de la limpieza del caché anteriores, los viejos cargador de clases todavía no se están recogiendo basura. Las restantes referencias al cargador de clases incluyen las siguientes:

  • las clases cargadas por el cargador de clases
  • de java.lang.Package creado por el propio cargador de clases
  • java.lang.ProtectionDomain creado por el cargador de clase en sí

Todo lo anterior son referencias circulares dentro del cargador de clases, lo que debería desencadenar una recolección de elementos no utilizados. No estoy seguro de por qué no lo es. ¿Alguien sabe por qué los viejos cargadores de clases todavía no se recogen basura, incluso con las referencias circulares?

+0

¿Qué JVM usas (versión exacta)? ¿Utiliza alguna opción de JVM que pueda afectar la carga de clases? ¿Utiliza algo de las implementaciones de Sun? ¿La aplicación manipula el código de bytes? ... ¿Cuál es el entorno que podría afectar la carga de clases? – cafebabe

+1

No está relacionado con su pregunta principal, pero ¿consideró algo así como OSGi en lugar de hacer su propio marco que admite la implementación en caliente? – SteveD

+0

@bfoo En nuestras pruebas, usamos Java 6. No hay opciones de JVM.No estamos usando la impl de Sun de nada en el caso más simple. Sin manipulación de código de bytes – onejigtwojig

Respuesta

15

Siempre escuché que la descarga de Classloader era problemática. Son theoretically basura recolectada cuando no hay referencia a las instancias del objeto y la descarga de la clase no es necesaria, pero en la práctica parece ser más problemático. Las referencias sutiles pueden tener fugas y evitar que se reclame Classloader. En los servidores de aplicaciones, después de numerosos ciclos de redespliegue, a veces obtengo un OutOfMemoryError: PermGen space.

Todo eso para decir que supongo que hay una referencia desagradable en alguna parte que impide que se recopile, tal vez el analizador de memoria no siguió el enlace correctamente. Parece que todo esto puede suceder, como se describe en estos artículos:

Además, no sé exactamente lo que está haciendo, pero si se puede esperar JDK 7, puedes echar un vistazo a AnonymousClassLoader. Serán presentados para apoyar mejor lenguaje dinámico, como se explica en este post:

espero que le ayudará.

+0

Una sub-aplicación es muy simple. La única biblioteca de terceros que utiliza es log4j. Nada más. El resto es la API JDK básica. También usa la clase ResourceBundle que mantiene el caché. Después de llamar a clearCache(), esas referencias desaparecieron, pero todavía no se recolecta la basura. Pero gracias por la respuesta :) – onejigtwojig

+0

ah, y por cierto, excelentes enlaces! – onejigtwojig

+0

Solo puedo sugerir probar con la sub-aplicación más simple (por ejemplo, con una clase) y luego agregar más y más clases y dependencias para ver en qué punto detiene el GC del cargador de clases. Pero sé que puede consumir mucho tiempo. Por cierto, Frank Kievet también escribió mensajes interesantes sobre transacciones XA, si estás interesado. – ewernli

Cuestiones relacionadas