La memoria de la Máquina Virtual se divide en algúnas regiones. Una de estas regiones es el PermGen el área de memoria utilizada para entre otras cosas guardar el metadata de las clases como los atributos y sus tipos de datos métodos etc. Esta memoria es de tipo non-heap. Las instancias de las clases se cargan en la memoria de tipo heap a la que se van añadiendo y eliminando las instancias de las clases según se van utilizando y eliminándose por el recolector de basura (Garbage Collector en adelante GC).

No vamos a entrar en el mecanismo de la carga y eliminación de clases en java porque excede este artículo pero sí lo comentaremos brevemente para poder comprender el porqué de la excepción OutOfMemoryException para que una clase pueda ser eliminada por el recolector de basura (GC) es indispensable que no esté referenciada por ninguna otra clase. Para que se pueda descartar la memoria ocupada por una clase en el lugar PermGen es indispensable además que se elimine el classloader que cargó la clase.

El valor por defecto del lugar PermGen es de 64 Mb en la máquina virtual (VM) de Sun. Este valor es suficiente usualmente para las aplicaciones que corren de manera independiente. En el caso de una aplicación que corra en un servidor web tipo Tomcat o un servidor de aplicaciones hay casos en los que este valor no es suficiente.

En primer lugar es probable que la aplicación necesite más lugar por su particular arquitectura. Las librerías Spring e Hibernate son librerías masivos que cargan muchas clases y además hacen uso de proxies y carga dinámica de clases que hacen uso del lugar PermGen por lo que puede que los 64Mb no sean suficientes. Este caso se da cuando la excepción con el yerro se produce nada mas arrancar el servidor web o de aplicaciones o al alcanzar a la aplicación. Para solventar este asunto bastará con crecer el dimensión máximo de la memoria de tipo PermGen según veremos más adelante.

En segundo espacio la motivo más posible de una excepción java.lang.OutOfMemoryError PermGen space failure se produce cuando la aplicación se reinstala en el servidor sin reiniciar el servidor. La manera de reinstalar las aplicaciones es eliminando el classloader que cargó la aplicación por primera vez y manerando un nuevo classloader para la nueva instancia de la aplicación. En teoría esto ofrece una manera limpia de reinstalar aplicaciones pero si el servidor web o de aplicaciones guarda una referencia al classloader antiguo se produce una fuga de memoria (memory leak) y el fruto es que tendremos las clases de la aplicación cargadas dos veces en memoria. Es cuestión del número de recargas y de la memoria gastada por la aplicación el que se produzca la excepción java.lang.OutOfMemoryError PermGen space failure. En este caso no basta con crecer el dimensión máximo de la memoria ya que esto sólo retrasaría el asunto a unas cuantas reinstalaciones más. En este caso la única solución consiste en averiguar la motivo de la fuga de memoria. Esto también excede el contenido de este artículo aunque lo intentarmos tratar con profundidad en otra ocasión. Por el momento sólo ofrecemos un enlace muy interesante aunque en inglés acerca de probables motivos de fugas de memoria en java //opensource.atlassian.com/confluence/spring/pages/viewpage.action?pageId=2669

Por último a continuación incluimos el argumento que es indispensable incluir al arrancar la máquina virtual para especificar el dimensión de esta región PermGen en Mb XXMaxPermSize=128m para el dimensión máximo y XXPermSize=128m para que la máquina virtual ya arranque con este dimensión y no tenga que reservar más lugar en tiempo de ejecución.