2010-10-03 15 views
95

Últimamente he estado leyendo mucho sobre esquemas de asignación de memoria en Java, y ha habido muchas dudas ya que he estado leyendo desde varias fuentes. Recogí mis conceptos y solicito revisar todos los puntos y comentarlos. Llegué a saber que la asignación de memoria es específica de JVM, así que debo decir de antemano, que mi pregunta es específica de Sun.Asignación estática en java - montón, pila y generación permanente

  1. clases (cargado por los cargadores de clases) van en una zona especial en el montón: Generación Permanente
  2. Toda la información relacionada con una clase como nombre de la clase, las matrices de objetos asscociated con la clase, los objetos internos utilizados por JVM (como java/lang/Object) y la información de optimización entra en el área de generación permanente.
  3. Todas las variables de miembros estáticos se mantienen nuevamente en el área de Generación permanente.
  4. Los objetos van en un montón diferente: Generación joven
  5. Solo hay una copia de cada método por clase, ya sea el método estático o no estático. Esa copia se coloca en el área de Generación permanente. Para los métodos no estáticos, todos los parámetros y variables locales van a la pila, y cada vez que hay una invocación concreta de ese método, obtenemos un nuevo stack-frame asociado a él. No estoy seguro de dónde se almacenan las variables locales de un método estático. ¿Están en el montón de la generación permanente? O solo su referencia se almacena en el área de Generación permanente, y la copia real está en otro lugar (¿Dónde?)
  6. Tampoco estoy seguro de dónde se almacena el tipo de devolución de un método.
  7. Si los objetos (en la generación joven) necesitan usar un miembro estático (en la generación permanente), se les da una referencia al miembro estático & & tienen suficiente espacio de memoria para almacenar el tipo de retorno del método , etc.

¡Gracias por pasar esto!

Respuesta

129

En primer lugar, debe quedar claro para usted que hay muy pocas personas que pueden confirmar estas respuestas de primera mano. Muy pocas personas han trabajado en las JVM recientes de HotSpot o las han estudiado hasta la profundidad necesaria para saber realmente. La mayoría de la gente aquí (yo incluido) está respondiendo en función de cosas que han visto escritas en otros lugares, o de lo que han deducido. Por lo general, lo que está escrito aquí, o en varios artículos y páginas web, se basa en otras fuentes que pueden ser definitivas o no. A menudo es simplificado, inexacto o simplemente incorrecto.

Si desea una confirmación definitiva de sus respuestas, realmente necesita descargar el código fuente de OpenJDK ... y investigue leyendo y entendiendo el código fuente. Hacer preguntas sobre SO o rastrear artículos web al azar no es una técnica de investigación académica sólida.

Una vez dicho esto ...

1) Clases (cargado por los cargadores de clases) van en un área especial en el montón: Generación Permanente.

AFAIK, sí. (Actualización: ver a continuación.)

2) Toda la información relacionada con una clase como nombre de la clase, las matrices de objetos asscociated con la clase, los objetos internos utilizados por JVM (como java/lang/Object) y la optimización de la información entra en la Generación Permanente zona.

Más o menos, sí. No estoy seguro de lo que quieres decir con algunas de esas cosas. Supongo que "los objetos internos utilizados por JVM (como java/lang/Object)" significa descriptores de clase internos de JVM.

3) Todas las variables de miembros estáticos se mantienen en el área de Generación permanente de nuevo.

Las variables en sí sí. Estas variables (como todas las variables de Java) contendrán valores primitivos o referencias a objetos. Sin embargo, mientras que las variables de miembro estático están en un marco que se asigna en el montón de permgen, los objetos/matrices a los que se refieren esas variables se pueden asignar en cualquier montón de.

4) Los objetos van en un montón diferente: la generación joven

No necesariamente

. Los objetos grandes pueden asignarse directamente a la generación permanente.

5) Solo hay una copia de cada método por clase, ya sea el método estático o no estático. Esa copia se coloca en el área de Generación permanente.

Suponiendo que se refiere al código del método, entonces AFAIK sí. Aunque puede ser un poco más complicado. Por ejemplo, ese código puede existir en códigos de bytes y/o en formas de códigos nativos en diferentes momentos durante la vida de la JVM.

... Para los métodos no estáticos, todos los parámetros y variables locales van a la pila, y cada vez que hay una invocación concreta de ese método, obtenemos un nuevo stack-frame asociado.

Sí.

... No estoy seguro de dónde se almacenan las variables locales de un método estático. ¿Están en el montón de la Genración Permanente? O solo su referencia se almacena en el área de Generación permanente, y la copia real está en otro lugar (¿Dónde?)

No. Se almacenan en la pila, al igual que las variables locales en métodos no estáticos.

6) Tampoco estoy seguro de dónde se almacena el tipo de devolución de un método.

Si se refiere al valor devuelto por una (no vacío) llamada al método, entonces se devolverán en la pila o en un registro de la máquina. Si se devuelve en la pila, toma 1 o 2 palabras, dependiendo del tipo de devolución.

7) Si los objetos (en la generación joven) Nees utilizar un miembro estático (en la generación permanente), se les da una referencia al miembro estático & & se les da suficiente espacio de memoria para almacenar el tipo de devolución del método, etc.

Eso es inexacto (o al menos, no se está expresando con claridad).

Si algún método tiene acceso a una variable miembro estática, lo que obtiene es un valor primitivo o un objeto referencia. Esto se puede asignar a una variable local o parámetro (existente), asignado a un miembro (existente) estático o no estático, asignado a un elemento (existente) de una matriz previamente asignada, o simplemente utilizado y descartado.

  • en ningún caso nueva necesidad de almacenamiento que se asignará a suscribir una referencia o un valor primitivo.

  • Normalmente, una palabra de memoria es todo lo que se necesita para almacenar un objeto o referencia de matriz, y un valor primitivo generalmente ocupa una o dos palabras, dependiendo de la arquitectura del hardware.

  • En ningún caso la persona que llama debe asignar espacio para mantener algún objeto/matriz devuelto por un método. En Java, los objetos y las matrices siempre se devuelven utilizando la semántica de pasar por valor ... pero ese valor que se devuelve es un objeto o una matriz de referencia.

ACTUALIZACIÓN

A partir de Java 8, el espacio PermGen se ha sustituido por metaespacio. Para obtener más información, consulte los siguientes recursos:

+1

Gran respuesta! ¿Esto también se aplica a Dalvik VM? – sinek

+4

No es así. Como mínimo, muchos detalles son diferentes. Por ejemplo, Dalvik no tiene un montón de permgen ... * per se *. –

+1

Cuando dice que las variables locales en un método se almacenan en la pila. ¿Significa que incluso si la variable local se instancia usando new()? – Peter

Cuestiones relacionadas