Pregunta

Estoy un poco confundido por el hecho de que en C # sólo los tipos de referencia Get basura recogida. Eso significa GC recoge únicamente los tipos de referencia para la memoria de asignación. Entonces, ¿qué ocurre con los tipos de valor, ya que también ocupan memoria en la pila?

¿Fue útil?

Solución

Para empezar, ya sea que estén en la pila o una parte de la pila depende de qué contexto Son parte de - si están dentro de un tipo de referencia, van a estar en el montón de todos modos. (Debe tener en cuenta la cantidad que realmente se preocupan por la brecha pila / pila de todos modos - como Eric Lippert ha escrito, es gran medida un detalle de implementación .)

Sin embargo, básicamente de memoria tipo de valor se recupera cuando se recupera el contexto - por lo que cuando la pila se extrae por el que regresaba de un método, que "Recupera" todo el marco de pila. Del mismo modo, si el valor de tipo de valor es en realidad parte de un objeto, entonces la memoria es recuperada cuando ese objeto se recoge la basura.

La respuesta corta es que usted no tiene que preocuparse por ello :) (Esto supone que no tiene nada otro que el recuerdo de que preocuparse, por supuesto - si usted tiene tiene estructuras con referencias a las manijas nativas que necesitan de liberación, que es un escenario un tanto diferente.)

Otros consejos

  

Estoy un poco confundido por el hecho de que en C # sólo los tipos de referencia Get basura recogida.

Esto no es un hecho. O, más bien, la verdad o la falsedad de esta afirmación depende de lo que entendemos por "obtener el recolector de basura". El recolector de basura sin duda se ve en los tipos de valor en la recogida; esos tipos de valores podrían ser vivo y se aferra a un tipo de referencia:

struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M(); 

cuando el recolector de basura se ejecuta sin duda se ve en s, ya que tiene que determinar que s.str sigue vivo.

Mi sugerencia: aclarar precisamente lo que entendemos por el verbo "obtiene basura recogida"

.
  

GC recoge únicamente los tipos de referencia para la memoria de asignación.

Una vez más, esto no es un hecho. Supongamos que tenemos una instancia de

class C { int x; }

la memoria para el número entero será en el montón de basura recogida, y por lo tanto reclamado por el recolector de basura cuando la instancia de C se convierte sin enraizar.

¿Por qué cree la falsedad de que sólo la memoria de los tipos de referencia se cancela la asignación por el recolector de basura? Lo correcto es que la memoria que fue asignaron por el recolector de basura es desasignado por el recolector de basura, que creo que tiene mucho sentido. El GC se asigna por lo que es responsable de la limpieza.

  

Entonces, ¿qué ocurre con los tipos de valor, ya que también ocupan memoria en la pila?

No hay nada en absoluto que les sucede. no necesita nada les ocurran. La pila es de un millón de bytes. El tamaño de la pila se determina cuando el hilo se pone en marcha; se inicia en un millón de bytes y se queda un millón de bytes largo de toda la ejecución del hilo. La memoria en la pila ni se crea ni se destruye; Sólo su contenido se cambian.

Hay muchos verbos utilizados en esta cuestión, como destruida, regeneradas, desasignado, eliminado. Que no se corresponde bien con lo que realmente sucede. Una variable local, simplemente deja de ser, noruega estilo loro .

Un método tiene un único punto de entrada, lo primero que sucede es que el puntero de pila CPU se ajusta. La creación de un "marco de pila", espacio de almacenamiento para las variables locales. Las garantías CLR que este espacio se inicializa a 0, de lo contrario no una característica utiliza fuertemente en C #, debido a la regla de asignación definitiva.

Un método tiene un único punto de salida, incluso si usted código de método está salpicada de múltiples declaraciones return. En ese momento, el puntero de pila es simplemente restaura a su valor original. En efecto se "olvida" que las variables locales donde quiera allí. Sus valores no son 'fregado' de ninguna manera, los bytes son todavía allí. Pero no van a durar mucho tiempo, la siguiente llamada en su programa se va a sobrescribir de nuevo. Las reglas CLR asegura cero inicialización que nunca se puede observar los valores antiguos, que serían inseguros.

Muy, muy rápido, no toma más de un ciclo de procesador único. Un visible efecto secundario de este comportamiento en el lenguaje C # es que los tipos de valor no pueden tener un finalizador. Asegurar ningún trabajo adicional se tiene que hacer.

un tipo de valor en la pila se elimina de la pila cuando se sale del ámbito.

tipos

valor son destruidos tan pronto como salen del ámbito de aplicación.

tipos de valor conseguiría desasignado cuando se retira el marco de pila después de que se haya ejecutado i asumiría

también quisiera añadir que la pila está en un nivel de rosca, y el montón es a nivel del dominio de aplicación.

Por lo tanto, cuando un extremos del hilo que se RECLAM la memoria de pila utilizado por ese hilo específico.

Cada instancia de tipo de valor en .NET serán parte de algo más, lo que podría ser una instancia de mayor valor que encierra tipo, un objeto montón, o un marco de pila. Siempre que cualquiera de esas cosas vienen a ser, cualquier estructura dentro de ellos también vendrán a la existencia; esas estructuras serán entonces seguirá existiendo siempre que lo contiene los cometa. Cuando la cosa que contiene la estructura deja de existir, la estructura también lo hará. No hay manera de destruir una estructura sin destruir el envase, y no hay manera de destruir algo que contiene una o más estructuras sin destruir las estructuras contenidas en él.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top