2010-12-30 17 views
53

Esta pregunta es para cualquiera que haya probado el botón "Buscar fugas" en el gestor de Tomcat y consiguió algunos resultados como este:¿Hay alguna forma de evitar las pérdidas de memoria por falta de implementación en Tomcat?

Las siguientes aplicaciones web fueron detenidos (recargado, sin desplegar), pero sus clases anteriores carreras todavía se cargan en la memoria, lo que provoca una pérdida de memoria (usar un perfilador confirmar):
/con fugas-app-name

estoy asumiendo que esto tiene algo que ver con que "el espacio Perm Gen" error que a menudo se obtiene con redespliegues frecuentes.

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 he intentado usar las siguientes opciones de JVM:

-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled

me vi salsas muy pequeño en la cantidad de espacio de Perm Gen usado, pero no lo que yo esperaba y los recuentos de clase cargada no lo hice soltar.

Entonces, ¿hay alguna manera de configurar Tomcat o diseñar su aplicación para que descargue mejor en un caso de baja? ¿O estamos trabajados con el reinicio del servidor después de algunas sesiones importantes de depuración?

Tomcat versión de salida:

versión del servidor: Apache Tomcat/6.0.29 Servidor
construida: 19 Julio 2010 1458
número de servidor: 6.0.0.29
Nombre del sistema operativo: Windows 7
OS versión: 6.1
Arquitectura: x86
JVM versión: 1.6.0_18-b07 vendedor
JVM: Sun Microsystems Inc.

Actualización:

Gracias a la respuesta Celias' me decidí a hacer un poco más de excavación y creo que determiné el culpable de estar en mis aplicación gracias a CXF, primavera 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).

Respuesta

15

Si desea asegurarse de no causar fugas que tiene que hacer lo siguiente:

  • Asegúrese de que su aplicación web no utiliza ninguna clase de Java que se encuentran en las bibliotecas compartidas contenedor web. Si tiene alguna bibliotecas compartidas, asegúrese de que no hay referencias fuertes a los objetos de dichas bibliotecas
  • Evitar el uso de variables estáticas, especialmente en objetos Java, como HashTable, conjuntos, etc. Si es necesario, asegúrese de que se llama a eliminar para liberar los objetos con los mapas, listas ...

Aquí también es un buen artículo sobre ThreadLocal y MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

+0

buena información! Traté de hacer una aplicación muy simple sin ningún tercero o bibliotecas compartidas y no vi los mismos síntomas que describí anteriormente. El único problema es que una aplicación del "mundo real" probablemente tendrá algunas pérdidas de memoria en algún lugar con el uso de libs de terceros. Así que supongo que todo se reduce a los desarrolladores en algún lugar de la línea. Estoy seguro de que todo lo que podíamos hacer mejoras: Tomcat, nuestras aplicaciones, bibliotecas ... – waltwood

+1

¿Alguien sabe más sobre el efecto de la generación de código de bytes dinámico, ya que es utilizado por muchos serializador XML, Hibernate, la tapicería? ¿Estas bibliotecas se descargan correctamente? – Codo

+0

Ok, fui precipitado al decir que no vi los mismos síntomas. Tal vez mi aplicación de prueba fue demasiado pequeña para notarla. Probé con la aplicación Tomcat Examples, y de nuevo vi que PermGen se llenaba y que las clases cargadas nunca volvían a la línea de base después de su desinstalación. Entiendo que PermGen se usa para almacenar metadatos sobre clases cargadas. Entonces, creo que un abandono debería hacer que Tomcat elimine las referencias de clase para una aplicación y el GC debería limpiarlas y subir sus metadatos ¿verdad? Incluso si mis clases contienen referencias fuertes a otras clases, ¿no deberían morir cuando Tomcat descarga las clases principales? – waltwood

6

Tomcat 7 se supone que traen mejoras en esta área. Consulte Features of Apache Tomcat 7, sección titulada ¡No más fugas!

Ellos 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, sólo puedo decir que he hecho la misma experiencia y no he encontrado 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.

Cuestiones relacionadas