Blog de Antonio Manuel Muñiz

Desarrollo, Ingeniería y Calidad del Software

Memoria PermGen en aplicaciones Java

¿Qué es la memoria PermGen?, de forma resumida se trata de la memoria usada por la máquina virtual Java para almacenar el código estático de las aplicaciónes que corren en ella.

¿Es posible que tengamos problemas con este tipo de memoria?, pues si, sobre todo en aplicaciones web que corren sobre un contenedor JSP/Servlet. La excepción que encontraremos será:

java.lang.OutOfMemoryError: PermGen space

¿Cómo es posible si mi código solo ocupa 1 MB y el límite de memoria PermGen es por defecto 64MB?, si tenemos en cuenta que sólo las librerías usadas por el contenedor pueden ocupar entre 20 y 30 MB, entonces no es tan disparatado. De todas formas seguimos teniendo un margen bastante amplio (unos 30 MB), pero a los 20-30 MB anteriores tenemos que sumarle el tamaño de las librerías de las que depende nuestra aplicación (normalmente en WEB-INF/lib), que si nos descuidamos levemente pueden alcanzar los 20 MB. Llegados a este punto casi hemos alcanzado los 64 MB.

¿Pero la máquina virtual carga el código en memoria bajo demanda?, cierto, aunque hay situaciones en que el código demandado no es solamente el utilizado por nuestra aplicación, un ejemplo claro es el uso de un ORM como Hibernate o un framework como Spring.

¿Cómo puedo monitorizar la memoria PermGen usada por mi aplicación?, con JPS y JSTAT, se trata de dos pequeñas utilidades incluidas en el JDK. En primer lugar debemos conocer el identificador del proceso Java que queremos monitorizar, para ello:

~/Antonio$ jps
  227
  336 WrapperSimpleApp
  340 Jps

En mi caso tengo corriendo una instancia de Plexus corriendo en mi máquina que corresponde al proceso 336. Para consultar la memoria PermGen que esta utilizando:

~/Antonio$ jstat -gcpermcapacity 336
  PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT
  8192,0     65536,0     25600,0     25600,0  24     4    0,457    0,866

De todos los datos mostrados nos interesa (en KBytes): la primera columna, tamaño mínimo reservado para la memoria PermGen; la segunda columna, tamaño máximo; tercera columna, memoria ocupada actualmente.

Evidentemente, si PGC (tercera columna) se aproxima a PGCMX debemos incrementar el máximo para la memoria PermGen incluyendo la siguiente opción en la inicialización de la máquina virtual:

-XX:MaxPermSize=256m

En mi caso sería en el script de incialización de Plexus. Es importante notar que la memoria reservada por la máquina virtual inicialmente será la suma de la memoria de datos inicial (heap) y la memoria de instrucciones inicial (PermGen), y similar para la memoria máxima.

Existen herramientas más completas e intuitivas que JSTAT, como Lambda Probe, pero no siempre tenemos la posibilidad de desplegar una aplicación en el contenedor para monitorizar estos parámetros, y mucho menos tocar el script arranque.

8 Respuestas a “Memoria PermGen en aplicaciones Java

  1. juan 23 septiembre 2008 en 9:37 pm

    tengo un problema con un jsp, este no muestra toda la informacion que segun debe tener, ya revise y no es error de codificacion, mas bien como que se queda sin memoria o algo asi porque no continua mostrando la informacion, tienen limite los jsp??

  2. Antonio Manuel Muñiz Martín 23 septiembre 2008 en 10:27 pm

    Hola Juan.

    La información que das no es mucha, pero en cualquier caso, si la máquina virtual no está lanzando ninguna excepción relacionada con la memoria entonces no debe existir ningún problema de memoria.

    Un saludo.

  3. Rafa 25 septiembre 2008 en 5:57 pm

    Estaba buscando como medir la memoria total usada por los objetos de generación permanente y encontré este post.

    Muchas gracias

  4. Antonio Manuel Muñiz Martín 25 septiembre 2008 en 6:15 pm

    Hola Rafa.

    Me alegra que te haya sido útil ;)

    Un saludo.

  5. esteban 27 octubre 2008 en 2:19 pm

    no se olviden del jconsole, aunque tambien hay que tocar ciertos parametros al iniciar la vm para conectarse.

  6. Antonio Manuel Muñiz Martín 27 octubre 2008 en 2:38 pm

    Hola Esteban.

    Precisamente estos días he estado intentando monitorizar Apache Continuum con JConsole. Lo he conseguido corriendo JConsole en la misma máquina en la que está Continuum, pero no lo he conseguido de forma remota.

    Un saludo.

  7. Iago 26 noviembre 2008 en 7:35 pm

    Hola,

    estoy haciendo un programa en Java y necesito conocer el estado de la memoria tras cada iteracion de un bucle, no con programas externos. Estoy buscando como poder hacerlo pero no he conseguido nada. si sabes como hacerlo me seria de mucha ayuda.

    Gracias

  8. Antonio Manuel Muñiz Martín 27 noviembre 2008 en 1:12 am

    Hola Iago,

    Puedes echarle un ojo a la clase MemoryUsage [1], quizás te ayude.

    [1] http://java.sun.com/javase/6/docs/api/java/lang/management/MemoryUsage.html

    Un saludo.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: