Espacio permanente vs espacio montón

79

Primero, ¿cuál es la diferencia entre el espacio de Perm y el espacio de pila (qué y cómo elige la JVM para usar cada espacio de memoria)?

En segundo lugar, pero lo más importante, ¿qué tipo de relación se recomendaría para una aplicación Java estándar de tipo MVC?

Gareth
fuente

Respuestas:

80

El montón almacena todos los objetos creados por su programa Java. El recolector de basura supervisa el contenido del montón, que libera memoria del montón cuando deja de usar un objeto (es decir, cuando no hay más referencias al objeto.

Esto contrasta con la pila , que almacena tipos primitivos como ints y chars, y normalmente son variables locales y valores de retorno de funciones. Estos no son basura recolectada.

El espacio de la permanente se refiere a una parte especial del montón. Vea esta respuesta SO para obtener una explicación: ¿Qué es el espacio permanente?

Olhovsky
fuente
1
El enlace que proporcionó dice "segmento de la pila", entonces, ¿es realmente "una parte especial de la pila"? Tendría mucho más sentido que fuera parte del montón (o incluso algún tipo de segmento de datos estáticos) en lugar de la pila que simplemente no es adecuada para ese tipo de cosas.
Sergei Tachenov
1
Es una parte especial del montón.
Edité
1
alguna recomendación sobre la segunda pregunta?
Gareth
2
@Gareth: Esto no es algo de qué preocuparse. Algunas JVM ni siquiera tienen una sección de memoria dedicada para el espacio de permanente. Si obtiene una excepción java.lang.OutOfMemory, visualice cuánto espacio de permanente se usa con esta herramienta: alphaworks.ibm.com/tech/pmat , y luego, si se queda sin espacio de permanente (poco común en mi experiencia) puede aumente el tamaño del espacio permanente con la opción de línea de comando -XX:MaxPermSize=256mpara establecer el tamaño del espacio permanente en 256 MB.
Olhovsky
1
OK veo. Entonces, realmente no hay ninguna regla de porcentaje ni nada. Gracias.
Gareth
34

Personalmente, no consideraría a PermGen como una parte especial del montón.

Preferiría pensar en el montón como un área de memoria dedicada a almacenar instancias de objetos, mientras que PermGen es un área dedicada a almacenar definiciones de clases. Como resultado, el ciclo de vida de un montón está vinculado a una aplicación, mientras que el ciclo de vida de PermGen está vinculado a una JVM.

Uno de los mejores ejemplos de por qué una aplicación y su JVM pueden tener un ciclo de vida diferente es en un contenedor Java EE. En un servidor de aplicaciones, las aplicaciones se pueden implementar y anular la implementación sin reiniciar el servidor. Durante la cancelación del despliegue (o redespliegue), es fácil liberar todas las instancias de objetos, es decir, el espacio de pila, pero es bastante complicado borrar todas las clases cargadas por esta aplicación de PermGen porque la JVM aún puede hacer referencia a algunas de las clases.

Uno de esos casos son los controladores con fugas . Cuando se implementa una aplicación, se carga un controlador JDBC y se registra con DriverManager. Cuando se anula la implementación de esta aplicación, DriverManager sigue vivo y contiene una referencia al controlador, su cargador de clases original y todo lo que cargó este cargador de clases. Como resultado, se crea una pérdida de memoria en PermGen, pero no es culpa de la administración de memoria de la aplicación.

Es cierto que las JVM como JRocket no tienen PermGen en absoluto, todo se almacena en el montón. Solo en ese contexto puede llamar a PermGen una "parte especial" del montón. Incluso entonces, deberíamos ver PermGen y el montón de manera diferente, ya que tienen un propósito muy diferente y tienen tipos muy diferentes de pérdidas de memoria.

Actualización : en el JDK 8 de Oracle, PermGen se reemplaza por "Metaspace" y ahora es oficialmente parte del montón. Ya no necesitaremos sintonizar específicamente PermGen.

Christopher Yang
fuente
0

NO puede dar nombres a la memoria asignada en el montón.

Eso significa que int x(su nombre) está asignado en la pila. Puede llegar al puntero por su nombre, por lo que el puntero está en la pila. No puede alcanzar el objeto por su nombre, porque no tiene nombre. Los accesos al objeto (sin nombre) deben ser por su puntero.

Pete Del Fina
fuente