Pregunta

Estoy ejecutando Tomcat6 en Sun's JRE6 y cada par de implementaciones me sale OutOfMemoryException: PermGen. He buscado en Google las soluciones de PermGen y he probado muchas soluciones. Ninguno funciona Leí muchas cosas buenas sobre JRockit de Oracle y cómo su asignación de PermGen puede ser de gran tamaño (en comparación con los 128M de Sun) y aunque no resuelve el problema, me permitiría volver a implementar 100 veces entre las excepciones de PermGen en comparación con 2 veces ahora.

El problema con JRockit es usarlo en la producción que necesita para comprar WebLogic que cuesta miles de dólares. ¿Qué otras opciones (gratuitas) existen que perdonen más la expansión de PermGen? ¿Cómo funcionan las siguientes JVM en esta área?

  • IBM JVM
  • Abrir JDK
  • Blackdown
  • Kaffe

... ¿otros?

Actualización: Algunas personas han preguntado por qué pensé que PermGen max era 128M. La razón es porque cada vez que intento elevarlo por encima de 128M, mi JVM no se inicializa:

[18-06-2009 01:39:44] [info] Se produjo un error durante la inicialización de VM [2009-06-18 01:39:44] [info] No se pudo reservar suficiente espacio para el montón de objetos [2009-06-18 01:39:44] [395 javajni.c] [error] Falló CreateJavaVM

Es extraño que falle al intentar reservar espacio para el montón de objetos , aunque no estoy seguro de que sea " el " montón en lugar de " a " montón.

Arranco la JVM con 1024MB iniciales y 1536MB max heap.

Cerraré esta pregunta ya que ha sido respondida, es decir. " la conmutación es inútil " y pregunte en su lugar ¿Por qué? ¿mi JVM de Sun falla con configuraciones de PermGen más grandes?

¿Fue útil?

Solución

Estoy de acuerdo con Michael Borgwardt en que puede aumentar el tamaño de PermGen, no estoy de acuerdo con que se deba principalmente a pérdidas de memoria. El espacio PermGen se consume agresivamente por aplicaciones que implementan un uso intensivo de Reflection. Básicamente, si tiene una aplicación Spring / Hibernate ejecutándose en Tomcat, prepárese para aumentar mucho ese espacio PermGen.

Otros consejos

¿Qué le dio la idea de que la JVM de Sun está restringida a 128M PermGen? Puede configurarlo libremente con la opción de línea de comandos -XX: MaxPermSize; el valor predeterminado es 64M.

Sin embargo, la verdadera causa de su problema es probablemente una pérdida de memoria en su aplicación que impide que las clases se recojan; Estos pueden ser muy sutiles, especialmente cuando están involucrados ClassLoaders, ya que todo lo que se necesita es una sola referencia a cualquiera de las clases, en cualquier lugar. Este artículo describe el problema en detalle y este sugiere formas de solucionarlo.

Técnicamente, el " PermGen " El grupo de memoria es una cosa de Sun JVM. Otras JVM no lo llaman así, pero todos tienen la idea de uno o más grupos de memoria no heap.

Pero si tiene un problema con permgen en su Sun JVM, cambiar a otra JVM es muy poco probable que resuelva algo, simplemente se manifestará con un nombre diferente.

Si múltiples redespliegues están causando sus problemas, simplemente aumente el PermGen de la VM a valores grandes. Intentamos JRockit hace un tiempo debido a este mismo problema, y ??sufre el mismo agotamiento de redistribución. Regresamos a SUn JVM.

Cambiar JVM no es una panacea. Puede obtener nuevos problemas inesperados (por ejemplo, consulte un artículo sobre el lanzamiento de una aplicación en 4 JVM diferentes).

  • Puede tener una pérdida de clase (por ejemplo, a través de cargadores de clase) que generalmente ocurre en la redistribución. Francamente, nunca he visto trabajar en redistribución en caliente en Tomcat (espero ver algún día).
  • Puede tener parámetros de JVM incorrectos (por ejemplo, para Sun JDK 6 de 64 bits -XX: + el interruptor UseParNewGC conduce a la pérdida del segmento de memoria PermGen. Si agrega interruptores adicionales: -XX: + UseConcMarkSweepGC -XX: + CMSClassUnloadingEnabled-XX: + CMSPermGenSweepingEnabled la situación se resolverá. Divertido, pero nunca conocí la fuga mencionada anteriormente con Sun JDK 6 32 bits). Enlace a un artículo " Tuning JVM Garbage Collection for Production Deployments " .
  • Su trozo PermGen puede no ser suficiente para cargar clases e información relacionada (en realidad, eso ocurre con mayor frecuencia después de volver a implementar bajo Tomcat, las clases antiguas permanecen en la memoria y las nuevas se están cargando)

Desde mi experiencia pasada, depurar ese tipo de fuga es uno de los tipos de depuración más complicados que he tenido.

[UPDATEDfont><

Artículo útil sobre cómo eliminar el enlace del cargador de clases en una nueva implementación de la aplicación.

Utilizo JRockit y sigo recibiendo errores de PermGen si no levanto (a través de -XX: MaxPermSize) la memoria. Tampoco puedo hacer que nada funcione para evitar esto (aparte de aumentarlo).

Perm gen es probablemente la memoria más simple de manejar, dudo que haya mucha diferencia entre las diversas implementaciones de vm.

Asegúrese de que todas las configuraciones de Tomcat que están marcadas como apagadas en producción estén apagadas en producción.

Sí, algunos marcos que generan muchas clases sobre la marcha, pero deberían estar limpiando por sí mismos, y, en cualquier caso, puede incluir más de unas pocas clases en 128Mb.

En serio, si perm gen sigue subiendo, entonces esa fuga debería corregirse, aunque puede que no sea su problema solucionarlo.

El IBM JVM no lo hace (y no lo hizo en 2009) tienen un permgen. Puede leer más sobre su Recolector de basura concurrente generacional que es su GC predeterminado para Java 7.

A veces ejecuté el Eclipse IDE en IBM JVM específicamente porque con mis complementos favoritos con frecuencia llenaba el permgen de HotSpot JVM. Claro, probablemente hubo una pérdida de memoria que alguien debería haber solucionado, pero mientras tanto mi IDE no fallaba y no estaba ocupado experimentando con diferentes configuraciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top