Estoy usando WildFly 11 Final y creé el siguiente EJB:

@Singleton
@Startup
public class MyDebug {
    private static final MyStaticSingleton myStaticSingleton = new MyStaticSingleton();
}

Ahora, si vuelvo a implementar la aplicación y miro el montón a través de JVisualVm, veré una instancia más de MyStaticSingleton por cada redistribución. Las instancias de MyStaticSingleton son referenciadas por diferentes ClassLoaders.

¿Es un comportamiento normal que el cargador de clases de una aplicación JavaEE no se descarte después de la implementación de una aplicación?

2
Thomas 16 oct. 2018 a las 17:44

2 respuestas

La mejor respuesta

Lo más probable es que tenga una fuga, causada por algún mal comportamiento de su aplicación. De hecho, ese es un problema bastante común.

El problema principal no es un número incrementado de instancias de su singleton, sino más bien un número incrementado de cargadores de clases y, por lo tanto, el número de clases cargadas (que finalmente podría ser enorme). Puede demostrarlo fácilmente con los volcados de javacore.

Para resolver eso, debe encontrar un objeto que evite que se descarten cada uno de estos cargadores de clases, y así todas las clases cargadas.

Un ejemplo bien conocido de este mal comportamiento de la aplicación EE es el uso de log4j con ganchos de apagado habilitados (habilitados de forma predeterminada).

ACTUALIZACIÓN

Solo para confirmar, el objeto referenciado estáticamente en el ejemplo dado no podría causar la pérdida de memoria nativa / cargadores de clases mencionados. Además, dado que el campo estático se declaró final, cumple la especificación EJB.

Como lo mencionó TS, el principal sospechoso es el grupo de conexiones, que viola la especificación EJB al ejecutar sus propios hilos.

El uso de subprocesos en el entorno EE, especialmente junto con los cargadores de clases de contexto, es una razón típica de tales fugas.

2
user3714601 17 oct. 2018 a las 19:16

La especificación EJB 3.2 (16.2.2) es clara en esto: ¡No debe hacer esto!

Un enterprise bean no debe utilizar campos estáticos de lectura / escritura. Se permite el uso de campos estáticos de solo lectura. Por lo tanto, se recomienda que todos los campos estáticos de la clase Enterprise Bean se declaren como finales.

Simplemente use un campo regular para su singleton y mueva la creación a @PostConstruct. Si el singleton también es algo administrado, use la inyección en este campo.

0
Frito 18 oct. 2018 a las 06:53