Asignación de memoria de tipos de valores y tipos de referencia en el marco .net

¿Hay algún artículo avanzado que pueda leer que pueda explicar cómo se asigna la memoria para diferentes tipos (valor y referencia) en .NET Framework.

por ejemplo, sabemos que a los tipos de valores se les asigna espacio en una stack, pero ¿cómo se gestiona?

Además, ¿cómo se gestionan los tipos de referencia en un montón y dónde se almacenan los valores reales? (El tipo de referencia como cualquier clase contendrá muchos tipos de valores, dónde se guardan y cómo se gestionan)

Es más complicado de lo que piensas Incluso su afirmación de que “los tipos de valores están asignados en la stack” no es correcta. Por ejemplo:

class Foo { int x; } 

int es un tipo de valor, pero el valor de x siempre estará en el montón porque se almacenará con el rest de los datos para la instancia de Foo, que es una clase.

Además, las variables capturadas para funciones anónimas y bloques de iteradores hacen la vida más difícil.

Tengo un artículo sobre la memoria de stack / stack C # que puede ser útil, pero también puede leer la publicación de blog de Eric Lippert sobre “La stack es un detalle de implementación” . En particular, un futuro comstackdor de C # podría decidir almacenar todas sus variables locales en el montón, usando la stack solo para mantener una referencia a una instancia creada al comienzo del método … que no desafiaría la especificación de C # en todas.

Un tipo de valor es “asignado” donde está definido.

Lo que eso significa depende de dónde lo defines:

  • En una clase / estructura, como un campo en esa estructura, ampliando la clase / estructura en la memoria para que se ajuste al valor del tipo de valor allí
  • Como una variable local en un método, en la stack, o como un registro, o como un campo en una clase generada (cuando se usan “cierres”), dependiendo de las optimizaciones
  • Como un parámetro para un método, en la stack o como un registro, dependiendo de las optimizaciones

Un tipo de referencia es una especie de valor dual. Un tipo de referencia es en el fondo un puntero, y el valor del puntero sigue las mismas reglas para “asignación” como un tipo de valor, pero una vez que se almacena un valor en él, es decir. una referencia a un objeto, ese objeto está en el montón en otro lugar.

En otras palabras, la variable de referencia en sí misma está “asignada” como un tipo de valor, pero el objeto al que se refiere está en el montón.

Cuando construyes un objeto de una clase, el espacio se asigna en el montón para que se ajuste a todos los campos de esa clase + algunos gastos generales en ese espacio.

Me parece recordar que Jon Skeet tiene un artículo sobre el tema, estoy seguro de que saltará con una respuesta muy pronto así que estad atentos.

Este artículo parece avanzado sin exagerar. Debería proporcionarle una mejor comprensión:

http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

Recuerde la regla, los tipos de referencia siempre van al Heap, mientras que los Value Types siempre van donde fueron declarados. Si un Tipo de valor se declara fuera de un método, pero dentro de un Tipo de referencia se colocará dentro del Tipo de referencia en el Heap.

Cuando se llama a un método, la cantidad de espacio requerida por los tipos de valores se conoce de antemano (puede ser calculada por el comstackdor). Este espacio se asigna en la stack y solo está disponible mientras dure la llamada al método. Para cada método nuevo, la memoria utilizada en la stack crece y, cuando el método sale, se reduce a su nivel anterior.

Los tipos de referencia se asignan en el montón. El montón es básicamente un bloque de memoria utilizado para ese propósito. Un objeto almacenado en el montón es principalmente los campos del objeto almacenado en la memoria asignada al objeto. Por lo tanto, los campos de tipo de valor se almacenan “dentro” del objeto en el montón. Los campos de tipo de referencia se almacenan como referencia (o puntero) del objeto al que se hace referencia. La memoria en el montón está gestionada por la recolección de basura. Es un tema complejo, pero la historia corta es que la memoria asignada a los objetos no utilizados en el montón se libera y, por lo tanto, es elegible para su reutilización a intervalos regulares por el recolector de basura.