2010-03-24 22 views
17

Hemos estado enfrentando errores de falta de memoria en nuestro servidor de aplicaciones por algún tiempo. Vemos que el tamaño del montón utilizado aumenta gradualmente hasta que finalmente alcanza el tamaño de montón disponible. Esto ocurre cada 3 semanas y luego se necesita reiniciar el servidor para solucionarlo. Al analizar los volcados de almacenamiento dinámico, encontramos que el problema es que los objetos se usan en JSP.¿Cómo liberar memoria?

¿Pueden los objetos JSP ser la causa real de los problemas de memoria de Appserver? ¿Cómo liberamos los objetos JSP (Objetos que están siendo instanciados usando usebean u otras etiquetas)?

Tenemos un servidor de aplicaciones Websphere en clúster con 2 nodos y un IHS.

EDIT: Los resultados anteriores se basan en el montón-dump y nativestderr análisis que figura a continuación utilizando el asistente de soporte de IBM

nativestd errar log de análisis de registro:

alt text http://saregos.com/wp-content/uploads/2010/03/chart.jpg

análisis de volcado de Heap:

! [Alt text] [2]

Análisis de volcado de pila que muestra los dominadores inmediatos (2 hasta niveles de entrada hastable en la imagen superior)

! [alt text] [3]

La última imagen muestra que los dominadores inmediatos están en los objetos de datos que se utilizan en las páginas JSP.

Edit2: Más información disponible en http://saregos.com/?p=43

+1

Recuerdo un viejo problema de pérdida de memoria relacionado con la implementación de JSP que no se había compilado previamente. El compilador Sun tenía una pérdida de memoria, los JSP se estaban compilando sobre la marcha, ya que se hizo referencia a que esto finalmente causó un error de falta de memoria. La solución fue precompilar los JSP antes de la implementación. – crowne

+0

pero en nuestro caso el agotamiento del montón es gradual ... la memoria se agota en 3 semanas. No parece un problema de precompilación. Además, precompilamos nuestras JSPs – sarego

+0

3 semanas, sin importar lo que se haga en la aplicación. ¿Usas alguna cosa relacionada con el temporizador? Suena como una acción periódica que no se lanza correctamente. –

Respuesta

7

desencadenar la recolección de basura manualmente no resuelve su problema - no va a liberar recursos que todavía están en uso.

Debe utilizar una herramienta de creación de perfiles (como jProfiler) para encontrar las fugas. Probablemente usas código que almacena referencias en listas o mapas que no se lanzan durante el tiempo de ejecución: referencias estáticas de manera propagable.

1

No hay objetos específicos para liberar asignados en JSP, al menos hasta donde yo sé. En lugar de investigar tales opciones, prefiero centrarme en encontrar el problema real en los códigos de la aplicación y solucionarlo.

Algunos consejos que pueden ayudar:

  • Comprobar el alcance de sus granos. No son , por ejemplo, almacenar algo usuario o solicitud específica en el alcance de la "aplicación" (por error)?
  • Compruebe la configuración del tiempo de espera de la sesión web en su aplicación web y la configuración del servidor de aplicaciones .
  • Mencionó que el consumo de pila crece gradualmente. Si es así, intenta ver cuánto crece el tamaño de montón con varios escenarios de usuario: Toma un heapdump, ejecuta una prueba, deja que el tiempo de espera de datos de sesión , tome otro volcado , compara los dos.Eso podría darle una cierta idea de donde no los objetos en el montón provienen de
  • Compruebe los granos que no haya fugas de memoria obvias, por supuesto :)

EDIT: Comprobación de recursos estáticos inéditos que Daniel menciona es otro que vale la pena cosa :)

8

Primero adjuntaré una herramienta de perfil para indicarle qué son estos "Objetos" que están ocupando toda la memoria.

Eclipse tiene TPTP, o JProfiler o JProbe.

Cualquiera de estos debe mostrar el montón de objetos que se está creando y le permite inspeccionarlo para ver qué hay en el montón.

Luego busque en la base de códigos para encontrar quién los está creando.

Quizás tenga un objeto de caché o árbol/mapa con elementos y solo haya implementado el método "igual()" en estos objetos, y deberá implementar "código hash()". Esto daría como resultado que el mapa/caché/árbol crezca y crezca hasta que se caiga. Esto es solo una suposición.

JProfiler sería mi primera llamada

JavaWorld tiene ejemplo captura de pantalla de lo que está en la memoria ...

alt text http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler16.gif

Y una captura de pantalla de la construcción objeto del montón y siendo limpiado (por lo tanto el borde de sierra)

alt text http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler19.gif

ACTUALIZACIÓN ****************************** *******************

Ok, me vería en ...

http://www-01.ibm.com/support/docview.wss?uid=swg1PK38940

que aumenta el uso del montón con el tiempo que lleva a una condición OutOfMemory . El análisis de una Heapdump muestra que las siguientes objetos están tomando una cantidad creciente de espacio:

40543128 [304] 47 clase

com/ibm/wsspi/Rasdiag/DiagnosticConfigHome 40539056 [56] 2 java/util/Hashtable 0xa8089170 40539000 [2064] 511 gama de java/util/Hashtable $ Entrada 6.300.888 [40] 3 java/util/Hashtable $ HashtableCacheHashEntry

+0

He analizado los heapdumps, los coredumps y el registro nativestderr y tengo la lista de objetos. El problema, sin embargo, es cómo solucionar el problema ... – sarego

+0

imágenes adjuntas al original qn ... – sarego

+0

wow nice heap size! :-) Ok, buscaría en el JSP cualquier mapa/hashmap/treemaps, etc. Voy a adivinar que en algún lugar alguien está colocando objetos en un hashmap con una clave String, y esa clave no es inquietante suficiente. O el objeto que es la clave no tiene implementados los métodos equal y hashcode. –

2

Si ejecuta bajo el Sol 6 JVM considerar seriamente la posibilidad de utilizar la jvisualvm programa en el JDK para obtener una visión general inicial de lo que realmente sucede dentro del programa. La comparación de instantáneas es realmente buena para ayudarlo a llegar más lejos en los objetos que entran sigilosamente.

Si Sun 6 JVM no es una opción, investigue qué herramientas de creación de perfiles tiene. Las pruebas pueden llegar muy lejos.

Puede ser algo tan simple como los arrays de caracteres gigantescos que subyacen a una subcadena que está recopilando en una lista, por ejemplo. gestión interna.

2

Sugiero leer Effective Java, chapter 2. A continuación, junto con un generador de perfiles, lo ayudará a identificar los lugares donde su aplicación produce pérdidas de memoria.

Liberar memoria no es la manera de resolver el consumo de memoria extensivo. El amplio consumo de memoria puede ser el resultado de dos cosas:

código
  • no está correctamente escrita - la solución es escribir de forma adecuada, de modo que no consume más de lo necesario - Java eficaz ayudará aquí.
  • la aplicación simplemente necesita tanta memoria. A continuación, se debe aumentar la memoria VM usando Xmx, Xms, XX:MaxHeapSize, ...
0

Según entiendo aquellas de nivel superior de memoria son comedores de almacenamiento y los objetos almacenados en el mismo caché. Probablemente deberías asegurarte de que tu caché liberará objetos cuando se necesita demasiada memoria. Es posible que desee utilizar weak-ref si necesita memoria caché solo para objetos vivos.

Cuestiones relacionadas