La garbage collection in pratica significa solo che gli oggetti allocati vengono automaticamente rilasciati ad un certo punto dopo che non sono più raggiungibili.
Più precisamente, vengono rilasciati quando diventano irraggiungibili per il programma, poiché gli oggetti con riferimenti circolari non verrebbero mai rilasciati altrimenti.
I puntatori intelligenti si riferiscono solo a qualsiasi struttura che si comporta come un normale puntatore ma ha alcune funzionalità extra associate. Questi includono, ma non sono limitati a deallocazione, ma anche controlli di copia, scrittura e rilegatura, ...
Ora, come hai affermato, i puntatori intelligenti possono essere utilizzati per implementare una forma di garbage collection.
Ma il treno del pensiero procede nel modo seguente:
- La raccolta dei rifiuti è una cosa interessante da avere, in quanto è conveniente e devo occuparmi di meno cose
- Pertanto: desidero la garbage collection nella mia lingua
- Ora, come posso ottenere GC nella mia lingua?
Certo, puoi progettarlo in questo modo dall'inizio. C # è stato progettato per essere garbage collection, quindi solo il new
tuo oggetto e verrà rilasciato quando i riferimenti non rientrano nell'ambito. Il modo in cui ciò viene fatto dipende dal compilatore.
Ma in C ++ non era prevista la raccolta dei rifiuti. Se allociamo un puntatore int* p = new int;
e questo non rientra nell'ambito, esso p
stesso viene rimosso dallo stack, ma nessuno si occupa della memoria allocata.
Ora l'unica cosa che hai dall'inizio sono i distruttori deterministici . Quando un oggetto lascia l'ambito in cui è stato creato, viene chiamato il suo distruttore. In combinazione con template e sovraccarico dell'operatore, è possibile progettare un oggetto wrapper che si comporta come un puntatore, ma utilizza la funzionalità distruttore per ripulire le risorse ad esso collegate (RAII). Lo chiami un puntatore intelligente .
Tutto ciò è altamente specifico per C ++: sovraccarico dell'operatore, modelli, distruttori, ... In questa particolare situazione linguistica, hai sviluppato degli indicatori intelligenti per fornirti il GC che desideri.
Ma se si progetta un linguaggio con GC dall'inizio, questo è solo un dettaglio di implementazione. Dici solo che l'oggetto verrà ripulito e il compilatore lo farà per te.
Puntatori intelligenti come in C ++ probabilmente non sarebbero nemmeno possibili in linguaggi come C #, che non hanno alcuna distruzione deterministica (C # aggira il problema fornendo zucchero sintattico per chiamare a .Dispose()
su determinati oggetti). Le risorse non referenziate verranno infine recuperate dal GC, ma non saranno definite esattamente quando ciò accadrà.
E questo, a sua volta, può consentire al GC di svolgere il proprio lavoro in modo più efficiente. Essendo integrato nel linguaggio più in profondità rispetto ai puntatori intelligenti, che sono impostati su di esso, .NET GC può ad esempio ritardare le operazioni di memoria ed eseguirle in blocchi per renderle più economiche o persino spostare la memoria in giro per aumentare l'efficienza in base alla frequenza con cui gli oggetti sono accessibili.