es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Despliegue de Spring Boot en Tomcat: fuga de permgen debido al registro de actividades.

Me encontré con un problema de fuga de memoria al redeployar una aplicación de spring boot 2.5 en tomcat 9.

Proceso de depuración:

  1. Ejecución de startup.bat de Tomcat
  2. Implementación de war
  3. Recarga/desimplementación de war
  4. Ejecución de Tomcat para encontrar fugas
  5. Comprobar las clases cargadas en visual vm

Tomcat findleaks informa de una fuga y visual VM indica que las clases no se descargan.

Próximos pasos:

  1. Tomar un heapdump
  2. Cargar el volcado en el analizador de memoria de Eclipse
  3. Listar objetos con referencias entrantes y filtrar a org.apache.catalina.loader.ParallelWebappClassLoader

Esto también lista los cargadores de clase con un estado DESTROYED. Para un cargador de clase destruido, haga lo siguiente:

  1. Ruta a las raíces de GC > Excluir todas las referencias de fantasmas/débiles/suaves/etc.

Esto indica que aún puede haber una referencia fuerte relacionada con org.apache.logging.log4j.core.jmx.StatusLoggerAdminMBean.

eclipse memory analyzer

Intenté recrear el problema en un proyecto simple de spring boot utilizando el registro de logback y log4j2. Ambos muestran el mismo escenario pero con una causa diferente (enganches de apagado).

La depuración y el código basado en el iniciador de spring boot se pueden encontrar aquí: https://github.com/webbres/spring-boot-permgen-issue/tree/master/debugging

En esta etapa, no estoy seguro si la fuga de permgen en mi aplicación real está relacionada con la del repositorio vinculado.

¿Hay medidas adicionales que deban tomarse que spring boot no esté manejando en relación con el uso de los marcos de registro en un war? He intentado agregar org.apache.logging.log4j:log4j-web como una dependencia, pero esto no parece resolver el problema del gancho de apagado en el proyecto de demostración.

Siento que estoy perdiendo algo…

Agregando -Dlog4j2.disable.jmx=true al CATALINA_OPTS y logging.register-shutdown-hook=false al application.properties, ya no veo referencias al filtrar las referencias de fantasmas/débiles/suaves/etc. Sin embargo, todavía veo la instancia DESTROYED del ParallelWebappClassLoader y las clases no están siendo descargadas.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Depurando un problema de pérdida de memoria con Spring Boot y Tomcat

    Descripción del problema

    Como experto de IT especializado en Spring Boot, Tomcat, Log4j y Log4j2, me encontré con un problema de pérdida de memoria al volver a implementar una aplicación “spring boot 2.5” en “tomcat 9”. Al recargar o anular la implementación del archivo WAR, el informe “findleaks” de Tomcat reporta una fuga y Visual VM indica que las clases no se descargan.

    Proceso de depuración

    Para depurar este problema, seguí el siguiente proceso:

    1. Inicié Tomcat utilizando startup.bat
    2. Implementé el archivo WAR
    3. Recargué/anulé la implementación del archivo WAR
    4. Usé el “findleaks” de Tomcat para buscar fugas
    5. Verifiqué las clases cargadas en Visual VM

    Pasos siguientes

    Después de comprobar las fugas y las clases cargadas, realicé un heapdump y lo cargué en Eclipse Memory Analyzer. Luego, listé los objetos con referencias entrantes y filtré la clase org.apache.catalina.loader.ParallelWebappClassLoader. Esto también listó los cargadores de clase con un estado DESTROYED. Para un cargador de clase destruido, seguí estos pasos:

    1. Ruta de las raíces de GC > Excluir todas las referencias fantasma/débiles/suaves/etc.

    Esto indicó que todavía podría haber una referencia fuerte relacionada con org.apache.logging.log4j.core.jmx.StatusLoggerAdminMBean.

    Intenté recrear el problema en un proyecto Spring Boot simple utilizando el registro de Logback y Log4j2. Ambos mostraron el mismo escenario, pero con una causa diferente (hooks de apagado).

    La depuración y el código basado en el iniciador de Spring Boot se pueden encontrar aquí: https://github.com/webbres/spring-boot-permgen-issue/tree/master/debugging

    En este momento, no estoy seguro si la fuga de Permgen en mi aplicación real está relacionada con la del repositorio vinculado.

    Pasos adicionales

    También estoy seguro si hay pasos adicionales que se deben realizar que el iniciador de Spring Boot no está manejando con respecto al uso de los marcos de registro en un archivo WAR. He intentado agregar org.apache.logging.log4j: log4j-web como una dependencia, pero esto no parece resolver el problema de los hooks de apagado en el proyecto de demostración.

    Agregar -Dlog4j2.disable.jmx=true en los CATALINA_OPTS y logging.register-shutdown-hook=false en los application.properties resulta en no obtener más referencias al filtrar todas las referencias fantasma/débiles/suaves/etc. Sin embargo, todavía veo la instancia DESTROYED de ParallelWebappClassLoader y las clases no se descargan.

    Conclusión

    En general, sospecho que el problema de la fuga de memoria está relacionado con el uso de Log4j o Log4j2 con Tomcat y Spring Boot. Se requiere más depuración para identificar la causa raíz y encontrar una solución.

Comments are closed.