In poche parole : i netturbini non usano la ricorsione. Controllano semplicemente la traccia tenendo traccia di essenzialmente due set (che possono combinarsi). L'ordine di tracciamento ed elaborazione delle celle è irrilevante, il che offre una notevole libertà di implementazione per rappresentare gli insiemi. Quindi ci sono molte soluzioni che in realtà sono molto economiche nell'uso della memoria. Ciò è essenziale poiché il GC viene chiamato proprio quando l'heap esaurisce la memoria. Le cose sono un po 'diverse con grandi memorie virtuali, poiché le nuove pagine possono essere facilmente allocate e il nemico non è mancanza di spazio, ma mancanza di localizzazione dei dati
.
Presumo che tu stia considerando di rintracciare i netturbini, non di contare i riferimenti per i quali la tua domanda non sembra valere.
UV
La prima cosa da notare è che tutti i GC di tracciamento seguono lo stesso modello astratto, basato sull'esplorazione sistematica del grafico diretto delle celle in memoria accessibile dal programma, in cui le celle di memoria sono vertici e i puntatori sono i bordi diretti. Utilizza per questo i seguenti set:
VVV= U∪ T
U
T
H
VUUT
UV
UcVUcUT
UUV= TVH- VV
VUUT
Salto anche i dettagli su ciò che è una cella, che si tratti di una o più dimensioni, come troviamo puntatori in esse, come possono essere compattati e una miriade di altri problemi tecnici che puoi trovare in libri e sondaggi sulla raccolta dei rifiuti .
U
Dove le implementazioni note differiscono è nel modo in cui questi insiemi sono effettivamente rappresentati. Molte tecniche sono state effettivamente utilizzate:
bit map: parte dello spazio di memoria viene conservato per una mappa che ha un bit per ogni cella di memoria, che può essere trovata utilizzando l'indirizzo della cella. Il bit è attivo quando la cella corrispondente si trova nell'insieme definito dalla mappa. Se vengono utilizzate solo bit map, sono necessari solo 2 bit per cella.
in alternativa, potresti avere spazio per un bit di tag speciale (o 2) in ogni cella per contrassegnarlo.
log2pp
puoi testare un predicato sul contenuto della cella e sui suoi puntatori.
è possibile spostare la cella in una parte libera della memoria destinata a tutte le sole celle appartenenti all'insieme rappresentato.
VTTU
puoi effettivamente combinare queste tecniche, anche per un singolo set.
Come detto, tutto quanto sopra è stato utilizzato da alcuni garbage collector implementati, strano come alcuni potrebbero sembrare. Tutto dipende dai vari vincoli dell'implementazione. E possono essere piuttosto economici nell'uso della memoria, probabilmente aiutati dall'elaborazione delle politiche degli ordini che possono essere scelte liberamente a tale scopo, poiché non contano per il risultato finale.
Quello che può sembrare il più strano, il trasferimento di celle in una nuova area, è in realtà molto comune: si chiama raccolta di copie. Viene utilizzato principalmente con la memoria virtuale.
Chiaramente non c'è ricorsione e non è necessario utilizzare lo stack dell'algoritmo mutatore.
Un altro punto importante è che molti GC moderni sono implementati per grandi memorie virtuali . Quindi ottenere spazio da implementare e un elenco o uno stack aggiuntivo non è un problema in quanto le nuove pagine possono essere facilmente allocate. Tuttavia, nelle grandi memorie virtuali, il nemico non è la mancanza di spazio ma la mancanza di località . Quindi, la struttura che rappresenta gli insiemi e il loro utilizzo deve essere orientata a preservare la località della struttura dei dati e dell'esecuzione del GC. Il problema non è lo spazio ma il tempo. Le implementazioni inadeguate hanno maggiori probabilità di mostrare un rallentamento inaccettabile rispetto all'overflow di memoria.
Non ho dato riferimenti a molti algoritmi specifici, risultanti da varie combinazioni di queste tecniche, poiché sembra abbastanza lungo.