Me pregunto si debo lidiar con los MBeans que están registrados directa o indirectamente desde mi aplicación que se implementa en un contenedor de servlets.JMX: ¿Cómo evitar las fugas de memoria de Classloader en un contenedor de servlets?
En la mayoría de los casos hay dos opciones para recuperar una MBeanServer
que se puede utilizar para registrar
crear su propia
MBeanServer
usandoMBeanServerFactory.createMBeanServer()
Uso
ManagementFactory.getPlatformMBeanServer()
Al utilizar la primera opción, es fácil anular el registro de todos los MBeans: Jus t invocar MBeanServer.releaseMBeanServer(myMBeanServer)
.
Pero, ¿qué pasa con la segunda opción que se utiliza a menudo en muchas aplicaciones de terceros? (y por cierto, esta también es la forma recomendada de Sun/Oracle).
Como se utiliza la plataforma MBeanServer
, no se cancelará el registro cuando se destruya el contexto del servlet, pero, lo que es peor, todavía contiene una referencia al cargador de clases de la aplicación web.
Como consecuencia, no se liberarán todas las referencias estáticas de la aplicación web, lo que provocará una fuga.
Si te gusta probar esto: Sólo desplegar una sencilla aplicación web que asigna una matriz de 100 MB que es referencias estática y que utiliza un controlador JDBC de Oracle (se registrará un MBean de diagnóstico utilizando el servidor mbean plataforma), desplegado en gato. Detenga la aplicación y reiníciela. Repita esto y verá OutOfMemoryError
.
Preguntas:
¿Tengo que hacer frente a estos problemas, en general, o se trata de un problema del contenedor de servlets y/o la biblioteca tercera parte?
¿Hay una manera de conseguir todos los MBeans de un
MBeanServer
qué clases se cargan por una específicaClassLoader
?¿Qué puedo hacer para evitar esto? ¿Debo hacer un seguimiento de todos los MBeans registrados en la plataforma
MBeanServer
y anular el registro durantecontextDestroyed()
?
Tal vez echar un vistazo a http://stackoverflow.com/questions/386892/is-it-necessary-to-unregister-an-mbean-from-the-platform-mbean-server – nfechner