Saya mengerti Rust tidak memiliki pengumpul sampah dan saya bertanya-tanya bagaimana memori dibebaskan ketika pengikatan keluar dari ruang lingkup.
Jadi dalam contoh ini, saya memahami bahwa Rust mengambil kembali memori yang dialokasikan ke 'a' ketika keluar dari ruang lingkup.
{
let a = 4
}
Masalah yang saya hadapi dengan ini, pertama bagaimana ini terjadi, dan kedua bukankah ini semacam pengumpulan sampah? Apa bedanya dengan pengumpulan sampah 'biasa'?
Jawaban:
Pengumpulan sampah biasanya digunakan secara berkala atau sesuai permintaan, seperti jika tumpukan mendekati penuh atau di atas ambang batas tertentu. Ia kemudian mencari variabel yang tidak digunakan dan membebaskan memorinya, tergantung pada algoritmanya .
Rust akan tahu ketika variabel keluar dari ruang lingkup atau masa pakainya berakhir pada waktu kompilasi dan dengan demikian memasukkan LLVM / instruksi perakitan yang sesuai untuk membebaskan memori.
Karat juga memungkinkan beberapa jenis pengumpulan sampah, seperti penghitungan referensi atom .
sumber
new()
fungsi yang diurapi seperti C, mereka hanya fungsi statis, dan khususnya sesuatu sepertilet x = MyStruct::new()
membuat objeknya di tumpukan. The nyata indikator alokasi heap adalahBox::new()
(atau salah satu struktur yang bergantung pada Box).Ide dasar dari pengelolaan sumber daya (termasuk memori) dalam sebuah program, apapun strateginya, adalah bahwa sumber daya yang terkait dengan "objek" yang tidak terjangkau dapat diperoleh kembali. Di luar memori, sumber daya tersebut dapat berupa kunci mutex, pegangan file, soket, koneksi database ...
Bahasa dengan pengumpul sampah secara berkala memindai memori (dengan satu atau lain cara) untuk menemukan objek yang tidak digunakan, melepaskan sumber daya yang terkait dengannya, dan terakhir melepaskan memori yang digunakan oleh objek tersebut.
Rust tidak memiliki GC, bagaimana cara mengelolanya?
Rust memiliki kepemilikan. Dengan menggunakan sistem tipe affine , ia melacak variabel mana yang masih memegang sebuah objek dan, ketika variabel seperti itu keluar dari ruang lingkup, memanggil destruktornya. Anda dapat melihat sistem tipe affine berlaku cukup mudah:
fn main() { let s: String = "Hello, World!".into(); let t = s; println!("{}", s); }
Hasil:
<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; ^
yang secara sempurna menggambarkan bahwa di setiap titik waktu, di tingkat bahasa, kepemilikan dilacak.
Kepemilikan ini bekerja secara rekursif: jika Anda memiliki
Vec<String>
(yaitu, deretan string dinamis), maka masingString
- masing dimilikiVec
olehnya sendiri yang dimiliki oleh variabel atau objek lain, dll ... jadi, ketika variabel keluar dari ruang lingkup, ia secara rekursif membebaskan semua sumber daya yang dimilikinya, bahkan secara tidak langsung. Dalam kasusVec<String>
ini berarti:String
Vec
itu sendiriDengan demikian, berkat pelacakan kepemilikan, masa pakai SEMUA objek program secara ketat terikat pada satu (atau beberapa) variabel fungsi, yang pada akhirnya akan keluar dari ruang lingkup (ketika blok tempat mereka berada berakhir).
Catatan: ini agak optimis, dengan menggunakan penghitungan referensi (
Rc
atauArc
) dimungkinkan untuk membentuk siklus referensi dan dengan demikian menyebabkan kebocoran memori, dalam hal ini sumber daya yang terkait dengan siklus tersebut mungkin tidak akan pernah dirilis.sumber
Dengan bahasa yang mengharuskan Anda mengelola memori secara manual, perbedaan antara tumpukan dan heap menjadi penting. Setiap kali Anda memanggil suatu fungsi, cukup ruang yang dialokasikan di stack untuk semua variabel yang ada dalam cakupan fungsi itu. Saat fungsi tersebut kembali, bingkai tumpukan yang terkait dengan fungsi itu "dikeluarkan" dari tumpukan, dan memori dibebaskan untuk digunakan di masa mendatang.
Dari sudut pandang praktis, pembersihan memori yang tidak disengaja ini digunakan sebagai sarana penyimpanan memori otomatis yang akan dihapus di akhir ruang lingkup fungsi.
Informasi lebih lanjut tersedia di sini: https://doc.rust-lang.org/book/the-stack-and-the-heap.html
sumber