Domanda

Sono un po 'confuso circa il fatto che in C # solo i tipi di riferimento ottengono garbage collection. Ciò significa GC raccoglie solo i tipi di riferimento per la memoria de-allocazione. Quindi, cosa succede con i tipi di valore in quanto occupano anche la memoria sulla pila?

È stato utile?

Soluzione

Per cominciare, se sono sulla pila o di una parte del mucchio dipende da quale contesto sono parte - se sono all'interno di un tipo di riferimento, saranno sul mucchio comunque. (Si dovrebbe considerare quanto vi preoccupate veramente il divario di stack / heap in ogni caso - come Eric Lippert ha scritto, è in gran parte un'implementazione dettaglio .)

Tuttavia, fondamentalmente memoria tipo di valore viene recuperata quando il contesto è recuperata - così quando la pila è spuntato dall'utente ritorno da un metodo, che "reclama" l'intera stack frame. Analogamente, se il valore del tipo valore è in realtà parte di un oggetto, la memoria viene recuperata quando l'oggetto viene garbage collection.

La risposta breve è che non dovete preoccuparvi di questo :) (Questo presuppone che non si ha nulla altro rispetto alla memoria di cui preoccuparsi, ovviamente - se hai ha ottenuto le strutture con riferimenti a maniglie nativi che hanno bisogno di rilascio, questo è uno scenario un po 'diverso.)

Altri suggerimenti

  

Sono un po 'confuso circa il fatto che in C # solo i tipi di riferimento ottengono garbage collection.

Non si tratta di un dato di fatto. O, piuttosto, la verità o la falsità di questa affermazione dipende da ciò che si intende per "ottenere il garbage collection". Il garbage collector sembra certamente a tipi di valore al momento del ritiro; questi tipi di valore potrebbe essere vivo e aggrappandosi a un tipo di riferimento:

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

quando il garbage collector gestisce sembra certamente a s, perché ha bisogno di determinare che S.Str è ancora vivo.

Il mio suggerimento:. Chiarire esattamente cosa si intende per il verbo "diventa garbage collection"

  

picconi GC solo i tipi di riferimento per la memoria de-allocazione.

Ancora una volta, questo non è un dato di fatto. Supponiamo di avere un esempio di

class C { int x; }

la memoria per l'intero sarà sull'heap garbage collection, e quindi recuperato dal garbage collector quando l'istanza di C diventa senza radice.

Perché si ritiene che la menzogna che solo il ricordo di tipi di riferimento viene deallocato dal garbage collector? L'affermazione corretta è che la memoria che è stato stanziati dal garbage collector è deallocato dal garbage collector, che a mio avviso ha perfettamente senso. Il GC allocata in modo che è responsabile della pulizia in su.

  

Quindi, ciò che accade con i tipi di valore in quanto occupano anche la memoria sulla pila?

Niente di niente accade loro. Nulla deve accadere a loro. Lo stack è un milione di byte. La dimensione dello stack è determinato quando il filo si avvia; inizia a un milione di byte e rimane un milione di byte nell'intero esecuzione del thread. Memoria sullo stack non è né creata né distrutta; solo il suo contenuto vengono modificati.

Ci sono troppi verbi utilizzati in questa domanda, come distrutto, bonificata, deallocata, rimosso. Che non corrisponde bene con ciò che effettivamente accade. Una variabile locale cessa semplicemente di essere, norvegese stile pappagallo .

Un metodo ha un unico punto di ingresso, prima cosa che succede è che lo stack pointer CPU viene regolata. Creazione di un "stack frame", lo spazio di archiviazione per le variabili locali. Le garanzie CLR che questo spazio viene inizializzato a 0, non altrimenti una caratteristica di utilizzare fortemente in C # a causa della regola di assegnazione definitiva.

Un metodo ha un unico punto di uscita, anche se si codice del metodo è disseminata di più istruzioni return. A quel punto, lo stack pointer viene semplicemente riportato al suo valore originale. In effetti si "dimentica" che le variabili locali dove mai lì. I loro valori non sono 'fregati' in alcun modo, i byte sono ancora lì. Ma non durerà a lungo, la chiamata successiva nel programma stanno andando a sovrascrivere di nuovo. La regola CLR zero inizializzazione assicura che non si può mai osservare quei vecchi valori, che sarebbe insicuro.

Molto, molto veloce, non richiede più di un singolo ciclo del processore. Una visibile effetto collaterale di questo comportamento nel linguaggio C # è che i tipi di valore non possono avere un finalizzatore. Garantire senza lavoro in più deve essere fatto.

Un tipo di valore nello stack viene rimossa dalla pila quando esce dall'ambito.

I tipi di valore sono distrutti non appena escono di portata.

tipi valore otterrebbero deallocato quando il telaio pila viene rimossa dopo che è stato eseguito Supporrei

vorrei anche aggiungere che stack è ad un livello di thread, e heap è al livello del dominio di applicazione.

Così, quando un thread termina sarebbe Reclam la memoria dello stack utilizzato da tale thread specifico.

Ogni valore del tipo di esempio NET sarà parte di qualcos'altro, che potrebbe essere un valore che racchiude tipo esempio più grande, un oggetto mucchio, o uno stack frame. Ogni volta che una di queste cose nascere, qualsiasi struttura all'interno di essi saranno anche venire in essere; quelle strutture saranno poi continuerà ad esistere finché la cosa che li contengono fa. Quando la cosa che contiene la struttura cessa di esistere, la struttura sarà pure. Non v'è alcun modo per distruggere una struttura senza distruggere il contenitore, e non c'è modo di distruggere qualcosa che contiene una o più strutture, senza distruggere le strutture in esso contenute.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top