2009-05-17 11 views
11

Tengo una pregunta¿Dónde se asigna la referencia de variable, en pila o en el montón?

Qué sucedió cuando declaro una variable dentro de un método, por ejemplo.

 
void myMethod() { 
    Ship myShip = new Ship(); 
} 

¿Dónde se asigna la referencia de myShip, en la pila o en el montón?

creo en la pila, pero estoy confundido porque yo estaba leyendo en J2ME juego libro de programación "clases Java se crean instancias en el montón de Java"

Todas las clases de Java?

Gracias de antemano

+0

Esta pregunta es un poco confusa como es. Podría ser "¿Dónde está guardada la memoria de myShip en la memoria?" o "¿Dónde está el objeto apuntado por myShip almacenado en la memoria?" La respuesta conceptual a la primera es la pila, y la respuesta conceptual a la última es el montón, salvo las optimizaciones y las implementaciones locas, y hay respuestas que responden en ambos sentidos. –

Respuesta

23

myShip es una referencia a un objeto Ship, myShip está en la pila de llamadas al método, que se conoce como "la pila". Cuando se llama un método, un bloque de memoria se coloca en la parte superior de la pila, ese bloque de memoria tiene espacio para todas las primitivas (int, float, boolean, etc.) y las referencias de objeto del método, que incluye los parámetros del método. El montón es donde se asigna la memoria para los objetos reales.

Así que myShip está en la pila y el objeto Ship está en el montón.

Nota: cada subproceso tiene su propia pila pero comparte el montón.

13

Java realmente hace las cosas un poco diferente. La referencia está básicamente en la pila. La memoria para el objeto se asigna en lo que pasa para el montón. Sin embargo, la implementación de memoria asignable no es exactamente como la forma en que se implementa el montón en el modelo C/C++.

Cuando crea un objeto nuevo como ese, efectivamente coloca el nombre en la tabla de referencias para ese ámbito. Eso es muy parecido a un puntero a un objeto en C++. Cuando sale del alcance, esa referencia se pierde; la memoria asignada ya no se referencia y se puede recolectar basura.

+0

¿Qué tal si solo fuera 'Ship ship;' Esto significa que la referencia del barco está en la pila, pero no se crea ningún objeto. Pero, ¿significa esto que la clase 'Ship' está cargada en este punto? – Joeblackdev

+0

¿De verdad? Pensé que hacer eso crea una referencia de Barco inicializada con nulo. ¿Hay una diferencia? – Joeblackdev

+3

@CharlieMartin: ¡Estás equivocado, Ship ship; no construyes un barco! La variable acaba de inicializarse en nulo. – tibo

6

Actualmente, todos los objetos de Java se asignan en el montón. Se habla de que Java 7 podría hacer un análisis de escape y ser capaz de asignar en la pila, pero no sé si la propuesta ya está finalizada. Here's the RFE.

Editar: Al parecer, es already in early builds of JDK 7. (El artículo dice que también estará en JDK 6u14, pero no puedo encontrar la confirmación.)

+2

El análisis de escape no afecta la semántica del código, sin embargo, uno nunca debería tener que confiar o asumir su existencia. – bdonlan

+2

@bdonlan: Correcto, sin embargo, el análisis de escape (implementado desde Java SE 6u23, btw) sí contribuye a que Java de hoy no sea el cojo que fue hace 15 años. –

3

Nocionalmente, el objeto continúa en "el montón". Entonces, como es una referencia local de método, la referencia real estará en la pila. Por "la" pila, nos referimos a la pila de subprocesos nativa (es decir, la misma pila en la que se asignaría una variable local en C) en el caso de la VM de Sun al menos, pero no creo que sea realmente un requisito (la JVM solo tiene que tener una noción abstracta de "marcos de pila" que asigna en cada llamada a método, ya sea desde la pila nativa o no).

Pero ... en las máquinas virtuales modernas (con la posible excepción de las máquinas virtuales integradas/mpbile), realmente no existe el "montón". En la práctica, hay varias áreas de montón. La más simple de estas es casi como una "mini pila", diseñada para ser rápida de asignar para objetos que no se mantendrán por mucho tiempo y probablemente puedan ser asignados casi de inmediato.

Según lo mencionado por otro afiche, una JVM altamente optimizada podría asignar datos de objeto en la pila y hay propuestas definitivas para esto. Aunque, como también se menciona en una de las referencias, una crítica de esto es que el montón rápido "eden" es casi como una pila de todos modos (simplemente no "la" pila).

Cuestiones relacionadas