memory - Problemas de PermGen con Lift y Jetty
scala jvm (5)
De esta publicación :
Esta excepción se produjo por una simple razón:
elpermgenspace
es donde las propiedades de clase, como métodos, campos, anotaciones y también variables estáticas, etc., se almacenan en la máquina virtual Java, pero este espacio tiene la particularidad de no ser limpiado por el recolector de elementos no utilizados. Entonces, si su aplicación utiliza o crea muchas clases (estoy pensando en generaciones dinámicas de clases), es probable que haya encontrado este problema. Aquí hay algunas soluciones que me ayudaron a deshacerme de esta excepción:
-
-XX:+CMSClassUnloadingEnabled
: esta configuración habilita la recolección de basura en el permgenspace -
-XX:+CMSPermGenSweepingEnabled
: permite que el recolector de basura elimine incluso las clases de la memoria -
-XX:PermSize=64M -XX:MaxPermSize=128M
: aumenta la cantidad de memoria asignada al permgenspace
Puede ser que esto podría ayudar.
Editar julio de 2012 (casi 3 años después):
Comentarios de Ondra Žižka (y he actualizado la respuesta anterior):
JVM 1.6.0_27 dice: Por favor use:
-
CMSClassUnloadingEnabled
(Ya sea que la descarga de clasesCMSClassUnloadingEnabled
habilitada cuando se usa CMS GC) - en lugar de
CMSPermGenSweepingEnabled
en el futuro
Vea las opciones de JVM de Hotspot completo: la referencia completa de mroe.
Estoy desarrollando en la plataforma Lift estándar (maven y embarcadero). Estoy repetidamente (una vez cada dos días) recibiendo esto:
Exception in thread "7048009@qtp-3179125-12" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN: handle failed
java.lang.OutOfMemoryError: PermGen space
Esto está en mi entorno de desarrollo. No es un problema porque puedo seguir reiniciando el servidor. En el despliegue, no estoy teniendo estos problemas, así que no es un problema real. Tengo curiosidad.
No sé mucho sobre la JVM. Creo que estoy en lo cierto al pensar que la memoria de generación permanente es para cosas como clases y cadenas internas. Lo que recuerdo es un poco mezclado con el modelo de memoria .NET ...
¿Alguna razón por la que esto está pasando? ¿Los valores predeterminados son increíblemente bajos? ¿Tiene que ver con todos los objetos auxiliares que Scala tiene que crear para objetos Function y cosas similares de FP? Cada vez que reinicio Jetty con un código recién escrito (cada pocos minutos), me imagino que volverá a cargar clases, etc. Pero aun así, no puede ser así, ¿no? ¿Y la JVM no debería poder tratar con un gran número de clases?
Aclamaciones
Joe
Esto se debe a la recarga de clases como sugirió. Si está utilizando muchas bibliotecas, etc. la suma de las clases crecerá rápidamente para cada reinicio. Intente controlar su instancia de embarcadero con VisualVM para obtener una visión general del consumo de memoria al volver a cargar.
La generación permanente es donde la JVM coloca cosas que probablemente no serán recolectadas (basura) como cargadores de clases personalizados.
Dependiendo de lo que esté desplegando, la configuración de perm gen puede ser baja. Algunas aplicaciones y / o combinación de contenedores contienen algunas pérdidas de memoria, por lo que cuando una aplicación queda sin desplegar a veces algunas cosas como cargadores de clases no se recopilan, lo que resulta en llenar el espacio Perm generando el error que está teniendo.
Desafortunadamente, actualmente la mejor opción en este caso es maximizar el espacio permanente con el siguiente indicador jvm (ejemplo para 192m de tamaño de memoria permanente):
-XX:MaxPermSize=192M (or 256M)
La otra opción es asegurarse de que el contenedor o el marco no pierdan memoria.
La lista de correo ( http://groups.google.com/group/liftweb/ ) es el foro de soporte oficial de Lift, y donde podrá obtener una mejor respuesta. No conozco los pormenores de su configuración de desarrollo (no entra en detalles), pero supongo que está recargando su guerra en Jetty sin realmente reiniciarla. El ascensor no realiza una generación dinámica de clases (como lo sugiere VonC más arriba), pero Scala compila cada cierre como una clase separada. Si agrega y quita cierres a su código en el transcurso de varios días, es posible que se carguen demasiadas clases y que nunca se descarguen y ocupen espacio permanente. Te sugiero que habilites las opciones opciones de JVM mencionadas por VonC arriba y veas si ayudan.
Si ve esto al ejecutar mvn jetty:run
, configure MAVEN_OPTS
.
Para Linux:
export MAVEN_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
Para ventanas:
set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
Debería estar bien ahora. Si no, aumente -XX:MaxPermSize
.
También puede poner estos permanentemente en su entorno.
Para Linux, agregue la línea de
export
a~/.bashrc
Para Windows, presione
Win-key + PrintScreen
, y vaya aAdvanced > Environment
. Vea también http://support.microsoft.com/kb/310519 .