java - ¿Hay alguna manera de evitar las pérdidas de memoria por falta de implementación en Tomcat?
spring memory-leaks (2)
Se supone que Tomcat 7 traerá mejoras en esta área. ¡Vea las características de Apache Tomcat 7 , sección titulada No More Leaks!
Creen que ahora pueden hacer frente a una gran cantidad de pérdidas de memoria causadas por las aplicaciones web. Desafortunadamente, todavía está en beta.
Aparte de eso, puedo decir que hice la misma experiencia y no encontré una solución. Desplegar generalmente requiere reiniciar Tomcat luego. No tengo idea de quién es el culpable: mi aplicación web, Tomcat, Hibernate, Tapestry o varios de ellos.
Esta pregunta es para cualquiera que haya probado alguna vez el botón "Buscar fugas" en el administrador de Tomcat y haya obtenido algunos resultados como este:
Las siguientes aplicaciones web fueron detenidas (recargadas, no desplegadas), pero sus clases de ejecuciones previas todavía están cargadas en la memoria, lo que provoca una pérdida de memoria (utilice un generador de perfiles para confirmar):
/ leaky-app-name
Supongo que esto tiene algo que ver con el error "Perm Gen space" que a menudo obtienes con redespliegues frecuentes.
Entonces, lo que estoy viendo en jconsole cuando implemente es que mis clases cargadas van desde aproximadamente 2k a 5k. Entonces, uno pensaría que un abandono debería volver a bajar a 2k, pero se mantienen en 5k.
También intenté usar las siguientes opciones de JVM:
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
Vi MUERTOS MÍNIMOS en la cantidad de espacio Perm Gen utilizado, pero no lo que esperaba y los recuentos de clases cargados no cayeron.
Entonces, ¿hay alguna manera de configurar Tomcat o diseñar su aplicación para que descargue mejor en caso de un abandono? ¿O estamos trabajados con el reinicio del servidor después de algunas sesiones importantes de depuración?
Salida de la versión Tomcat:
Versión del servidor: Apache Tomcat / 6.0.29
Servidor construido: 19 de julio de 2010 1458
Número de servidor: 6.0.0.29
Nombre del sistema operativo: Windows 7
Versión del sistema operativo: 6.1
Arquitectura: x86
Versión JVM: 1.6.0_18-b07
Vendedor de JVM: Sun Microsystems Inc.
Actualizar:
Gracias a la respuesta de Celias, decidí investigar un poco más y creo que determiné que el culpable era estar en mi aplicación gracias a CXF, Spring y JAXB.
Después de aprender a perfilar una aplicación Java, señalé el generador de perfiles en Tomcat y tomé algunos volcados del montón e instantáneas para ver cómo se veían los objetos y las clases en la memoria. Descubrí que algunas de las enumeraciones de mi esquema XML usadas en mis clases generadas CXF / JAXB (wsdl2java) estaban persistiendo después de un despliegue incompleto. Según mi volcado de montón, parece que los objetos estaban atados a un Mapa. Descargo de responsabilidad: admito que todavía estoy un poco verde con los perfiles y el seguimiento del árbol de llamadas de un objeto puede ser un desafío en Java.
También debo mencionar que ni siquiera invoqué el servicio, simplemente lo desplegué y luego lo desinstalé. Los propios objetos parecían estar cargados a través de la reflexión iniciada desde Spring en la implementación. Creo que seguí la convención para configurar un servicio CXF en primavera. Por lo tanto, no estoy 100% seguro de que esto sea Spring / CXF, JAXB o error de reflexión.
Como nota al margen: la aplicación en cuestión es un servicio web que utiliza Spring / CXF y el XML resulta ser un esquema bastante complejo (una extensión de NIEM ).
Si quiere asegurarse de no causar fugas, debe hacer lo siguiente:
- Asegúrese de que su aplicación web no use ninguna clase de Java que se encuentre en las bibliotecas compartidas del contenedor web. Si tiene bibliotecas compartidas, asegúrese de que no haya referencias fuertes a los objetos en esas bibliotecas
- Evite el uso de variables estáticas, especialmente en objetos Java como HashTable, Sets, etc. Si es necesario, asegúrese de llamar a eliminar para liberar los objetos con los mapas, listas ...
Aquí también hay un buen artículo sobre ThreadLocal y MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/