2010-04-02 4 views
16

Vi ayer una pregunta que planteó (para mí) otra pregunta. Por favor, mire el siguiente código:Campos de clase, ¿están almacenados en la pila o en el montón?

public class Class1 
{ 
    int A; //as I uderstand, int is value type and therefore lives in the stack 
} 

class Class2 
{ 
    Run() 
    { 
     Class1 instance1 = new Class1(); 
     instance1.A = 10; //it points to value type, but isnt this reference (on heap)? 
    } 
} 

O al crear la instancia de Clase 1, sus tipos de campo se crean en el montón así? Pero entonces no entiendo cuándo realmente estaría en la pila, ya que casi siempre necesitas crear una instancia de objeto para usar los campos.

+0

Los nombres de clases no se les permite empezar con un número – cpalmer

+0

fuera de tema: usted tiene los nombres de clases no válidos más allá – thelost

+0

gracias, fijo :) – Mirek

Respuesta

3

Las variables de estructura local (tipo de valor) se almacenan en la pila, los campos de tipo de valor de una clase se almacenan en el montón.

+7

A menos que (1) el varaible local sea el local externo cerrado de un método anónimo o expresión lambda, o (2) el local se encuentre en un bloque iterador, o (3) la fluctuación decida usar registros en lugar de la pila. –

+0

qué pasa con la variable instancia1 en lo que se refiere a su almacenamiento. Es un tipo de referencia, pero al mismo tiempo es local para la función Ejecutar(). ¿Se guardará la instancia 1 en la pila o en el montón? – RBT

+0

Lo siento @EricLippert por otro comentario pero estaba tratando de editar mi anterior pero no pude hacerlo a tiempo. Para agregar claridad a mi pregunta anterior, quiero preguntar dos cosas: 1. donde se guardará la instancia de referencia1. instancia1 es solo una referencia que contiene una dirección de memoria donde residirá la instancia de objeto real 2. donde residirá el objeto, instancia de Clase1 referida por instancia1. Aquí el objeto es una instancia de Class1 pero tiene un alcance local en el método Run(). – RBT

2

Ok int es un tipo de valor pero '1' (qué horrible nombre para una clase) es un tipo de referencia. Esto significa que cualquier instancia de '1' está en el montón.

36

como yo lo entiendo, es int tipo de valor y por lo tanto vive en la pila

Su comprensión es incorrecta. Los tipos de valores se llaman "tipos de valor" porque se copian por valor. Los tipos de referencia se llaman "tipos de referencia" porque se copian por referencia. No es del todo cierto que "los tipos de valores siempre vivan en la pila". Si eso fuera cierto, se llamarían "tipos de pila" y "tipos de montón".

La verdad es que este es un detalle de implementación. Diferentes implementaciones de framework pueden elegir usar la pila y el montón como quieran. Así es como lo hace la implementación de Microsoft:

  • el valor de una variable de tipo de referencia es una referencia a la memoria del montón. Una referencia es básicamente un entero de 32 o 64 bits.
  • el valor de una variable de tipo de valor es su valor.
  • los valores de las variables locales se almacenan en la pila a menos que las variables locales estén en un bloque de iterador o sean variables externas cerradas de un método anónimo o una expresión lambda. En esos casos, los valores de las variables locales se almacenan en el montón. A menos, por supuesto, que las variables locales puedan optimizarse, en cuyo caso no habrá almacenamiento. O tal vez se puedan registrar, en cuyo caso no están ni en la pila ni en el montón, están en los registros del procesador.
  • los valores de las variables de instancia de los tipos de referencia y las variables estáticas se almacenan en el montón.

¿Está claro?

apunta al tipo de valor, pero ¿no es esta referencia (en el montón)?

El campo "A" es del tipo de valor. Es un campo, y por lo tanto esa variable se almacena en el montón.

Al crear la instancia de Clase 1, ¿sus tipos de campo también se crean en el montón?

El almacenamiento para las variables de instancia está en el montón, sí.

Pero entonces no entiendo cuando realmente estaría en la pila ya que casi siempre es necesario crear una instancia de objeto para poder usar sus campos.

Nunca estaría en la pila. Como dije antes, las únicas cosas que van en la pila son las variables locales (y las temporales generadas por el compilador) que no son locales cerrados de un método lambda o anónimo y no están en un bloque iterador. Y, por supuesto, el jitter es libre de mantenerlos fuera de la pila por completo y ponerlos en registros si hay registros gratuitos.

Pero en realidad, tengo que preguntar, ¿por qué te importa lo que va en la pila y lo que va en el montón? Lo que pasa en la pila es algo que podemos poner barato en la pila; todo lo demás sigue en el montón.

+0

Tengo el libro de John Sharp que dice "Los tipos de valores se crean en la pila mientras que los tipos de referencia en el montón". No lo entiendo, también. – Thomas

+0

"los valores de la instancia y las variables estáticas se almacenan en el montón". Excepto por las variables de instancia estructuradas de una instancia que se ha almacenado en la pila, ¿verdad? – Joren

+2

"por qué te importa lo que pasa en la pila y lo que sucede en el montón", porque a algunos entrevistadores les gustan mucho esas preguntas y mucha gente no las realizó porque está escrito en todas partes que las variables int siempre se almacenan en la pila, no "Lo único que va en la pila son las variables locales" – Laserson

Cuestiones relacionadas