Trasforma la tua domanda in giro. La vera domanda motivante è in quali circostanze possiamo evitare i costi della raccolta dei rifiuti?
Bene, prima di tutto, quali sono i costi della raccolta dei rifiuti? Ci sono due costi principali. Innanzitutto, devi determinare cosa è vivo ; ciò richiede potenzialmente molto lavoro. Secondo, devi compattare i buchi che si formano quando liberi qualcosa che è stato allocato tra due cose che sono ancora vive. Quei buchi sono dispendiosi. Ma compattarli è anche costoso.
Come possiamo evitare questi costi?
Chiaramente se riesci a trovare un modello di utilizzo dello storage in cui non allochi mai qualcosa di lunga durata, quindi alloca qualcosa di breve durata, quindi alloca qualcosa di lunga durata, puoi eliminare il costo dei buchi. Se puoi garantire che per alcuni sottogruppi della tua memoria, ogni allocazione successiva ha una vita più breve della precedente in quella memoria, allora non ci saranno mai buchi in quella memoria.
Ma se abbiamo risolto il problema del buco , abbiamo risolto anche il problema della raccolta dei rifiuti . Hai qualcosa in quel deposito ancora vivo? Sì. Tutto è stato assegnato prima che durasse più a lungo? Sì, questo presupposto è come abbiamo eliminato la possibilità di buchi. Pertanto è sufficiente dire "è attiva l'allocazione più recente?" e sai che tutto è vivo in quella memoria.
Abbiamo una serie di allocazioni di archiviazione in cui sappiamo che ogni allocazione successiva ha una durata inferiore rispetto all'allocazione precedente? Sì! I frame di metodi di attivazione vengono sempre distrutti nell'ordine opposto rispetto a quando sono stati creati perché hanno sempre una vita più breve rispetto all'attivazione che li ha creati.
Pertanto, possiamo archiviare i frame di attivazione nello stack e sapere che non devono mai essere raccolti. Se nella pila è presente un fotogramma, l'intera serie di fotogrammi sottostanti ha una durata maggiore, quindi non è necessario che vengano raccolti. E saranno distrutti nell'ordine opposto rispetto alla loro creazione. Il costo della raccolta dei rifiuti viene quindi eliminato per i frame di attivazione.
Ecco perché abbiamo il pool temporaneo nello stack in primo luogo: perché è un modo semplice di implementare l'attivazione del metodo senza incorrere in una penalità di gestione della memoria.
(Ovviamente il costo della spazzatura che raccoglie la memoria a cui fanno riferimento riferimenti nei frame di attivazione è ancora lì.)
Consideriamo ora un sistema di flusso di controllo in cui i frame di attivazione non vengono distrutti in un ordine prevedibile. Cosa succede se un'attivazione di breve durata può generare un'attivazione di lunga durata? Come puoi immaginare, in questo mondo non puoi più usare la pila per ottimizzare la necessità di raccogliere attivazioni. L'insieme di attivazioni può contenere nuovamente buchi.
C # 2.0 ha questa funzionalità sotto forma di yield return
. Un metodo che fa un rendimento ha intenzione di essere riattivato in un secondo momento - la prossima volta che viene chiamato MoveNext - e quando ciò accade non è prevedibile. Pertanto, le informazioni che sarebbero normalmente nello stack per il frame di attivazione del blocco iteratore vengono invece archiviate nell'heap, dove vengono raccolte garbage quando viene raccolto l'enumeratore.
Allo stesso modo, la funzione "asincrona / attende" disponibile nelle prossime versioni di C # e VB consentirà di creare metodi le cui attivazioni "producono" e "riprendono" in punti ben definiti durante l'azione del metodo. Poiché i frame di attivazione non vengono più creati e distrutti in modo prevedibile, tutte le informazioni che erano memorizzate nello stack dovranno essere archiviate nell'heap.
È solo un incidente della storia che ci è capitato di decidere per alcuni decenni che le lingue con frame di attivazione che sono stati creati e distrutti in un modo rigorosamente ordinato erano alla moda. Poiché alle lingue moderne manca sempre più questa proprietà, aspettatevi di vedere sempre più lingue che reiterano le continuazioni sul mucchio raccolto dall'immondizia, piuttosto che sulla pila.