outofmemoryerror maxpermsize java memory-leaks memory-management

outofmemoryerror - maxpermsize java 8



¿Por qué está creciendo el espacio de PermGen? (7)

He leído algunos artículos y entendí lo siguiente (corríjame y / o edite la pregunta si me equivoco):

El montón de Java está segmentado de esta manera:

  • Generación joven: los objetos que se crean van aquí, esta parte se recolecta de manera frecuente y económica.

  • Old Generation: los objetos que sobreviven a las recolecciones de basura de la generación Young van aquí, esta área es la recolección de basura con menos frecuencia y utiliza un proceso / algoritmo más exigente de CPU (creo que se llama mark-sweep)

Edición: según lo indicado por otro usuario, PermGen no es parte de la región llamada heap

  • PermGen: esta área está llena de metadatos de clases de su aplicación y muchas 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 una carga pesada? Por lo que dije antes, este espacio no debería llenarse de manera incremental 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 una forma de recolección de basura o restablecerlo?


¿Estás haciendo algo funky con la cadena classloader? ¿Estás llamando a intern() en un montón de cadenas?


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

Si su generación permanente crece constantemente, es un área difícil de explorar. En general, debería crecer cuando las nuevas clases se cargan por primera vez (y esto podría causar ciertos usos potenciales de la reflexión). Las cadenas internas también se almacenan en perm gen.

Si está en Solaris, podría usar jmap -permstat para volcar las estadísticas de perm gen, pero esa opción no parece estar disponible en Windows (y potencialmente en otras plataformas). Aquí está la documentación en jmap para Java 6.

De la guía de Sun en JConsole (que te permitirá ver el tamaño de estos grupos):

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

  • Eden Space (heap): el grupo desde el cual la memoria se asigna inicialmente para la mayoría de los objetos.
  • Espacio de sobreviviente (montón): el grupo que contiene objetos que han sobrevivido a la recolección de basura del espacio de Eden.
  • Generación permanente (heap): la agrupación que contiene objetos que han existido durante algún tiempo en el espacio del sobreviviente.
  • Generación permanente (no de pila): la agrupación que contiene todos los datos reflexivos de la máquina virtual, como los objetos de clase y método. Con las máquinas virtuales de 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 de pila): la máquina virtual HotSpot Java 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.



Las causas más comunes que he visto son:

  1. Las clases de java estan cargadas
  2. JAXBContext.newInstance
  3. String.intern ()

Las causas más comunes que he visto son:

  • Cargadores de clases personalizados que no liberan cuidadosamente las clases antiguas después de cargar otras nuevas.
  • Clases restantes en PermGen después de volver a implementar una aplicación varias veces (más común en Dev que 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 una sola definición de clase podría reutilizarse para múltiples instancias.