Blog de Antonio Manuel Muñiz

Desarrollo, Ingeniería y Calidad del Software

Archivos por Etiqueta: PermGen

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.