12 de marzo de 2010

Desenlace de las pruebas de uso de memoria en nuestra aplicación Icefaces

Esta semana hemos seguido diagnosticando errores de memoría. Y por fin hemos dado con la solución: ni goteo de memoria, ni Icefaces, ni JSF, ni nada. Al final el servidor se caía porque se quedaba sin memoria, pero memoria que necesitaba realmente.

Os preguntareis, ¿por qué no fue lo primero que probasteis (subir el limite máximo de memoria de la JVM con el parámetro -Xmx)? Y la respuesta es: por dos motivos, el primero que la aplicación está en producción de un cliente muy grande y no es tan fácil cambiar esos parámetros sin argumentar por qué. El segundo: que si no sabemos si es que necesita más memoria o es que tiene un goteo, no parece muy ético subir el parámetro y dejarlo correr.

Esto último tiene un nombre: solución de problemas/programación por coincidencia. Es una práctica que, lamentablemente, estoy harto de ver y que consiste en dar palos de ciego toqueteando todo hasta que funciona. Y cuando funciona "me olvido y tiro p'alante", sin saber realmente si se ha arreglado o no, ni por que se ha arreglado.

No lo hagais más, anda :-P.

En fin, al grano, al final el problema es que nos habían reservado 256MB para la JVM y, después de dar un OutOfMemoryError, analizando un volcado del heap de la JVM resulta que de 100MB de heap que teníamos disponibles (sí, los otros 156MB se los comía el servidor de aplicaciones él solito) 81MB estabán ocupados por la clase WebAppClassLoader. Efectivamente, nuestro WAR ocupa 50MB y el classloader se lo tiene que guardar casi entero en memoria (tened en cuenta que lo que más ocupa en una aplicación web suelen ser los JAR) porque almacena el contenido de cada .class en un array de bytes más otras cositas asociadas.

Conclusión: nos quedaban unos 19MB para ejecutar nuestra aplicación. Y eso habiendo cargado solo un 70% de las clases totales de la aplicación. Así que, la solución propuesta ha sido subir el limite a 512MB y seguir probando.

Yo tengo fe en que se solucione, pero si vuelve a fallar, volveremos a hacer más pruebas, y volveré a abrasaros con otro artículo ;-P.

8 comentarios:

  1. Si, parece que no pero el tamaño de las librerías que cascamos en WEB-INF/lib es un factor importante a tener en cuenta a la hora del consumo de memoria. Así que dependencias las justas y necesarias, pero nada más.
    A ese respecto, un "efecto" muy curioso. Si se reinicia el contexto, voluntaria o involuntariamente, puedes apostar los calcetines a que alguna de las librerías provoca un memory leak en el WebAppClassLoader (una inmensa mayoría de librerias populares como las Jakarta Commons y drivers JDBC sufre este problema) y eso significa que todos esos .jar no se liberan, lo cual son 81MB perdidos de golpe... y voilà, la tan odidada OOME al reiniciar el contexto.

    No es algo que suela pasar en producción, pero en desarrollo es un dolor de webs, y en producción no te deja tocar apenas cosas sin reiniciar todo el puñetero servidor de aplicaciones y tirar todas las aplicaciones al suelo durante X segundos.

    ResponderEliminar
  2. El problema de tener muchas clases definidas y que luego no se liberan es peliagudo y hay que tener en cuenta que a veces subir la memoria heap no basta, ya que el problema esta en la parte PermGen de la memoria, y esa hay que aumentarla con otro parámetro.

    PD: Interesante tema, una pena que los programadores Java lo traten a veces tan superficialmente por que es "problema de sistemas". Cuando en realidad es un problema donde todos han de meter mano.

    EJ
    Happy Coding!

    ResponderEliminar
  3. Llevais razon en todo lo que decis. En las recargas de contexto suelen aparecer problemas. Normalmente mas de PermGen que de OOM, porque las clases van en el PermGen.

    Desgraciadamente el cliente en el que estamos mirando esto tiene software del pleistoceno (JDK1.4 y Sun One Web Server -7.1 creo recordar) y hay ni PermGen, ni JConsole ni cristo que lo fundo. Es un dolor de muelas poder diagnosticar nada en su entorno.

    De ahi que haya tenido que recurrir a hacer un core dump de Solaris, para luego pasarlo al jmap, para luego evaluarlo con Eclipse. A mi me gusta mas hacer estas cosas en tiempo real que en plan forense, pero es lo que hay.

    ResponderEliminar
  4. ¿Y no podeis evaluar la parte soft al menos en otra maquina con mas herramientas? Con Java 6, JConsole, incluso el YourKit o lo que haga falta...

    No es lo mismo que evaluar una replica del sistema, pero al menos de la parte pura de Java podeis sacar una idea más clara y ver si ahí está el problema.

    Cuando no, al menos le podreis decir al cliente... "con las versiones más modernas no pasa, a ver si te actualizas chato" :) (si, ya sé que no es tan sencillo" :P

    ¡Suerte y que te sea leve!
    EJ
    Happy Coding!

    ResponderEliminar
  5. No, si eso es lo que hemos hecho. Hemos probado un Tomcat en Windows con Java5 y otro con Mac en Java6. Precisamente gracias a eso sabemos que nuestra aplicación no parece tener memory leaks.

    De hecho en el entorno del cliente tampoco hay memory leaks. Lleva dos semanas funcionando con un heap de 512MB sin ningun problema. El rollo es que el Sun One coge mogollon de memoria para las clases. Muchisimo mas en relacion al Tomcat (no se por que, tampoco lo he estudiado a fondo).

    Total que ni memory leak ni nada, era memoria que hacia falta y punto.

    Y en cuanto a lo de convencer al cliente para usar Java6 o similares es absolutamente imposible. Desgraciadamente no evolucionan nada o casi nada. Nos costo dios y ayuda convencerles para usar JSF (aunque seguro que esto a greeneyed le parece bien ;-D). De Struts tampoco quieren oir hablar. Lo hacen todo a pelo, sin frameworks ni nada, con codigo en los JSPs y demas.

    En fin, una lastima...

    ResponderEliminar
  6. ¡Dios mío! ¿Les convencéis para usar JSF y no para usar Java 6? Ojo que me parece que eso está prohibido por la Convención de Ginebra y cualquier día de estos os aparece Amnistía Internacional a meteros un puro :X :X

    A pelo en JSP/JSF... ¿y en vez de móvil usan tam-tams? Como lleva tantos años usándose he oído que es mucho más fiable :D

    En fin, suerte.

    PD: Un día tenemos que hacer un intercambio de frameworks. Tu me explicas como va el tuyo y lo pruebo y viceversa... aunque luego me tenga que lavar entero con jabón para eliminarme el olor a JSF, jejeje.

    ResponderEliminar
  7. Si yo te contara... Y si supieras de que cliente se trata...

    Te tomo la palabra de lo de los framework, pero primero tenemos que liberarlo, que aun no esta ni subido. Cuando lo tengamos y me de el visto bueno el cliente que lo va a liberar te cuento. ¿El tuyo en open source? ¿Esta publico?

    Por lo de JSF no te apures, que casi todo lo hacemos por encima y no usamos casi nada de JSF (mas que nada porque es un framework bastante limitadito y complejo, al menos en su version 1).

    En cuanto a la limpieza yo aun no te he confesado que el XML+XSL tambien me da alergia, asi que vamos a estar en situacion parecida, no te preocupes... :-DD

    ResponderEliminar
  8. El nuestro(mío) sí está publicado y es OS desde 1999 o así. Se llama WebLEAF y algunos enlaces interesantes son:
    .- Web del proyecto: https://webleaf.dev.java.net/
    .- Documentación:
    https://swww.uib.es/webleaf/confluence//x/-w
    .- Artículo en java.net sobre como usarlo con Groovy y FreeMarker o XSLT:
    http://today.java.net/pub/a/today/2007/06/19/mvc-webappps-with-groovy-scripting-and-webleaf.html
    .- La traducción al castellano del anterior:
    https://swww.uib.es/webleaf/confluence//x/AYCw
    .- Documentación de la charla/taller que dí sobre usar diferentes lenguajes en la JVM (usando WebLEAF aunque no es sobre eso la charla):
    https://swww.uib.es/webleaf/confluence//x/AoBpAQ
    .- Aplicación Demo/Showcase con diferentes opciones de implementación de lógica y de interfaz...: http://www.greeneyed.org/test/
    .- Esta última aplicación también es OS y está en: https://webleaftest.dev.java.net/

    Con eso tienes para un empacho :). Pero vamos, se como están las cosas, el tiempo que la gente tiene y lo "interesante" que te puede ser, así que sin compromisos, tranquilo.

    S!

    ResponderEliminar