L'idea di base della gestione delle risorse (inclusa la memoria) in un programma, qualunque sia la strategia, è che le risorse legate ad "oggetti" irraggiungibili possono essere recuperate. Oltre alla memoria, queste risorse possono essere blocchi mutex, handle di file, socket, connessioni al database ...
Le lingue con un garbage collector analizzano periodicamente la memoria (in un modo o nell'altro) per trovare oggetti inutilizzati, rilasciare le risorse ad essi associate e infine rilasciare la memoria utilizzata da quegli oggetti.
Rust non ha un GC, come gestisce?
Rust ha la proprietà. Utilizzando un sistema di tipo affine , tiene traccia di quale variabile sta ancora trattenendo un oggetto e, quando tale variabile esce dall'ambito, chiama il suo distruttore. Puoi vedere il sistema di tipi affini in vigore abbastanza facilmente:
fn main() {
let s: String = "Hello, World!".into();
let t = s;
println!("{}", s);
}
Rendimenti:
<anon>:4:24: 4:25 error: use of moved value: `s` [E0382]
<anon>:4 println!("{}", s);
<anon>:3:13: 3:14 note: `s` moved here because it has type `collections::string::String`, which is moved by default
<anon>:3 let t = s;
^
il che illustra perfettamente che in qualsiasi momento, a livello di lingua, la proprietà viene tracciata.
Questa proprietà funziona in modo ricorsivo: se si dispone di un Vec<String>
(ovvero, un array dinamico di stringhe), ciascuna String
è di proprietà del Vec
quale a sua volta è di proprietà di una variabile o di un altro oggetto, ecc ... quindi, quando una variabile esce dall'ambito, libera ricorsivamente tutte le risorse che aveva, anche indirettamente. In questo caso Vec<String>
significa:
- Rilascio del buffer di memoria associato a ciascuno
String
- Rilascio del buffer di memoria associato allo
Vec
stesso
Pertanto, grazie al rilevamento della proprietà, la durata di TUTTI gli oggetti del programma è strettamente legata a una (o più) variabili di funzione, che alla fine usciranno dall'ambito (quando il blocco a cui appartengono termina).
Nota: questo è un po 'ottimistico, utilizzando il conteggio dei riferimenti ( Rc
o Arc
) è possibile formare cicli di riferimenti e quindi causare perdite di memoria, nel qual caso le risorse legate al ciclo potrebbero non essere mai rilasciate.