2010-01-12 27 views
17

He leído algunos artículos, y entendí lo siguiente (por favor, corríjanme y/o editar la pregunta si estoy equivocado):¿Por qué está creciendo el espacio PermGen?

almacenamiento dinámico de Java está segmentado como esto:

  • generación joven: objetos que se crean ir aquí, esta parte es frecuente y poco costosa basura recogida

  • vieja generación: los objetos que se conservan las colecciones de basura de la generación joven ir aquí, esta zona es basura recogida con menos frecuencia y usando una más proceso/algoritmo exigente de la CPU (creo se llama marca y barrido)

Editar: según lo declarado por otro usuario, PermGen no es una parte de la región llamada heap

  • PermGen: esta zona está llena de su aplicación clases de metadatos y muchos otras cosas que no dependen del uso de la aplicación.

Entonces, sabiendo esto ... ¿por qué mi espacio PermGen crece cuando la aplicación está bajo mucha carga? Por lo que dije antes, este espacio no debería llenarse gradualmente a pesar de la carga de la aplicación, pero como dije al principio probablemente me equivoque sobre algunas suposiciones.

De hecho, si el espacio de PermGen está creciendo, ¿hay alguna forma de recogerlo o restablecerlo?

+0

¿Podría aclarar más sobre lo que está sucediendo cuando crece su perm gen? ¿Cómo estás observando que tu gen de la permea está creciendo? –

Respuesta

19

En realidad, en Sun's JVM Permanent Generation (PermGen) está completamente separado del montón. ¿Estás seguro de que no estás mirando a la generación de Tenured? De hecho, sería sospechoso si su Generación permanente siguiera creciendo.

Si su perm gen está creciendo constantemente, es un área difícil de excavar. Por lo general, debería crecer cuando se carguen nuevas clases por primera vez (y posiblemente ciertos usos de la reflexión también podrían causar esto). Las cadenas internas también se almacenan en perm gen.

Si está en Solaris, puede usar jmap -permstat para volcar las estadísticas de gen perm, pero esa opción no parece estar disponible en Windows (y potencialmente en otras plataformas). Aquí es the documentation on jmap for Java 6

de Sun guide on JConsole (que le permitirá ver el tamaño de estas piscinas):

Para el Java HotSpot VM, la memoria piscinas para la recolección de basura en serie son los siguientes.

  • Eden Space (heap): El conjunto desde el que inicialmente se asigna la memoria para la mayoría de los objetos.
  • Survivor Space (Heap): el grupo que contiene objetos que han sobrevivido la recolección de basura del espacio Eden .
  • Generación sostenida (heap): grupo que contiene objetos que han existido durante algún tiempo en el espacio del superviviente.
  • Generación permanente (no acumulativa): el conjunto que contiene todos los datos reflectantes de la máquina virtual en sí, como objetos de clase y método. Con máquinas virtuales Java que utilizan el intercambio de datos de clase, esta generación se divide en áreas de solo lectura y de lectura y escritura.
  • caché de código (no apilable): la máquina virtual Java de HotSpot también incluye un caché de código, que contiene la memoria que se utiliza para la compilación y el almacenamiento del código nativo .
2

¿Estás haciendo algo moderno con la cadena de carga de clases? ¿Está llamando al intern() en un montón de cadenas?

+0

No, la "parte pesada" de la aplicación radica en deserializar un gran gráfico de objetos, pero el gráfico es principalmente HashMaps con cadenas dentro. Tal vez eso es llamar 'interno '? –

+2

No.HashMap no llama a pasante(). –

6

Las causas más comunes que he visto son:

  • cargadores de clases personalizados que no lo hacen con cuidado liberar más viejas clases después de cargar los nuevos.
  • Clases restantes en PermGen después de volver a implementar una aplicación varias veces (más común en Dev que en Prod)
  • Uso intensivo de clases Proxy, que se crean sintéticamente durante el tiempo de ejecución. Es fácil crear nuevas clases Proxy cuando se puede reutilizar una única definición de clase para varias instancias.
6

Este es uno de los problemas más molestos para depurar. Hay muchas razones por las que podría estar viendo el aumento del uso de permgen. Aquí hay 2 enlaces que encontré muy útiles tanto para entender cómo ocurren las filtraciones como para rastrear qué es lo que está causándolas.

http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html

http://frankkieviet.blogspot.com/2006/10/classloader-leaks-dreaded-permgen-space.html

+0

+1 para los enlaces increíbles. Me encontré con uno de estos la semana pasada, pero desde entonces perdí el enlace. –

0

Las causas más comunes que he visto son: clases

  1. Java se cargan
  2. JAXBContext.newInstance
  3. String.intern()
Cuestiones relacionadas