¿Quien no ha tenido problemas de memoria en tomcat? el famoso java.lang.OutOfMemoryError: PermGen space. Esta memoria PermGen es usada para almacenar el código de las aplicaciones que corren en ella.
¿Por qué me quedo sin memoria? Debemos entender que no sólo ocupa memoria nuestro código, sino también las librerias, y esto pueden ser unos cuantos Mb que vamos metiendo en memoria.
¿Cómo saber en qué valores de memoria nos andamos? Tenemos dos comandos Java: jps y jstat que vienen en el JDK.
- El jps es como un ps de Unix, nos indica los procesos Java que están en ejecución, devolviendo el PID del programa.
- El jstat nos permite ver la memoria que usa ese proceso. El parámetro para ver la capacidad actual es «-gccapacity PID» y para medir sólo la memoria PermGen es «-gcpermcapacity PID»
Ejemplos:
[www@villacarralon scripts]$ jps
25873 Jps
18156 Bootstrap
[www@villacarralon scripts]$ ps -ef | grep java
www 18156 1 0 09:12 pts/0 00:00:49 /servicio/jdk1.5.0_11//bin/java -server ... org.apache.catalina.startup.Bootstrap start
www 25882 18101 0 11:08 pts/0 00:00:00 grep java
jstat -gccapacity 18156
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
58240,0 116480,0 58304,0 8128,0 8640,0 41024,0 466048,0 932096,0 466048,0 466048,0 131072,0 262144,0 131072,0 131072,0 24 0
jstat -gcpermcapacity 18156
PGCMN PGCMX PGC PC YGC FGC FGCT GCT
131072,0 262144,0 131072,0 131072,0 24 0 0,000 0,555
Tenemos tres valores interesantes a observar para la memoria PermGen:
- el PGCMN: el tamaño mínimo reservado para la memoria PermGen
- el PGCMX: la memoria máxima que puede usar (en KB)
- el PGC, la memoria usada actualmente.
Si vemos que el PGC se aproxima al PGCMX deberíamos de cambiar la opción del tomcat aumentando el tamaño máximo con -XX:MaxPermSize=256m a por ejemplo -XX:MaxPermSize=512m siempre que nuestro equipo nos lo permita.
Si necesitamos monitorizarlo durante una ejecución, podemos plantearnos hacer un scriptillo como:
#!/bin/bash
jps | grep Bootstrap | awk '{print "while true; do jstat -gcpermcapacity " $1 "; sleep 5; done" }' | bash