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?
¿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
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
@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