แนวคิดพื้นฐานในการจัดการทรัพยากร (รวมถึงหน่วยความจำ) ในโปรแกรมไม่ว่าจะเป็นกลยุทธ์ใดก็ตามคือทรัพยากรที่เชื่อมโยงกับ "วัตถุ" ที่ไม่สามารถเข้าถึงได้นั้นสามารถเรียกคืนได้ นอกเหนือจากหน่วยความจำทรัพยากรเหล่านั้นอาจเป็นล็อค mutex ที่จับไฟล์ซ็อกเก็ตการเชื่อมต่อฐานข้อมูล ...
ภาษาที่มีตัวรวบรวมขยะจะสแกนหน่วยความจำเป็นระยะ ๆ (ไม่ทางใดก็ทางหนึ่ง) เพื่อค้นหาวัตถุที่ไม่ได้ใช้ปล่อยทรัพยากรที่เกี่ยวข้องและปล่อยหน่วยความจำที่ใช้โดยวัตถุเหล่านั้นในที่สุด
สนิมไม่มี GC จัดการอย่างไร?
สนิมมีความเป็นเจ้าของ การใช้ระบบประเภท Affineจะติดตามตัวแปรที่ยังคงยึดอยู่กับวัตถุและเมื่อตัวแปรดังกล่าวอยู่นอกขอบเขตจะเรียกตัวทำลายของมัน คุณสามารถดูระบบประเภท affine ได้อย่างง่ายดาย:
fn main() {
let s: String = "Hello, World!".into();
let t = s;
println!("{}", s);
}
ผลตอบแทน:
<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;
^
ซึ่งแสดงให้เห็นอย่างสมบูรณ์แบบว่าเมื่อใดก็ตามที่ระดับภาษาจะมีการติดตามความเป็นเจ้าของ
เจ้าของนี้ทำงานซ้ำ: ถ้าคุณมีVec<String>
(เช่นอาร์เรย์แบบไดนามิกของสตริง) จากนั้นแต่ละคนString
เป็นเจ้าของโดยVec
ที่ตัวเองเป็นเจ้าของโดยตัวแปรหรือวัตถุอื่น ฯลฯ ... ดังนั้นเมื่อตัวแปรออกไปข้างนอกขอบเขต มันปลดปล่อยทรัพยากรทั้งหมดที่มีอยู่ซ้ำ ๆ ซ้ำ ๆ แม้ในทางอ้อม ในกรณีVec<String>
นี้หมายถึง:
- การปล่อยบัฟเฟอร์หน่วยความจำที่เกี่ยวข้องกับแต่ละ
String
- การปล่อยบัฟเฟอร์หน่วยความจำที่เกี่ยวข้องกับ
Vec
ตัวมันเอง
ดังนั้นด้วยการติดตามความเป็นเจ้าของอายุการใช้งานของอ็อบเจ็กต์โปรแกรมทั้งหมดจะเชื่อมโยงอย่างเคร่งครัดกับตัวแปรฟังก์ชันหนึ่ง (หรือหลายตัว) ซึ่งท้ายที่สุดจะออกไปนอกขอบเขต (เมื่อบล็อกที่อยู่ในนั้นสิ้นสุดลง)
หมายเหตุ: นี่เป็นแง่ดีเล็กน้อยโดยใช้การนับอ้างอิง ( Rc
หรือArc
) เป็นไปได้ที่จะสร้างวงจรของการอ้างอิงและทำให้เกิดการรั่วไหลของหน่วยความจำซึ่งในกรณีนี้ทรัพยากรที่เชื่อมโยงกับวัฏจักรอาจไม่ถูกปล่อยออกมา