Rust में मेमोरी प्रबंधन: क्यों कोई गार्बेज कलेक्टर नहीं है और यह कैसे काम करता है

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

गार्बेज कलेक्टर क्या है और Rust ने इसे क्यों छोड़ा?

\n\n

यदि आप Python, Java या C# की दुनिया से आए हैं, तो आप इस बात के आदी हैं कि मेमोरी का प्रबंधन गार्बेज कलेक्टर (Garbage Collector, GC) द्वारा किया जाता है। यह एक अदृश्य "सफाईकर्मी" है, जो समय-समय पर जाँचता है कि कौन सी वस्तुएँ अब उपयोग में नहीं हैं, और उनके द्वारा घेरी गई मेमोरी को मुक्त करता है। सुविधाजनक? हाँ। लेकिन इसमें कुछ बारीकियाँ हैं:

\n\n
    \n
  • अप्रत्याशित ठहराव। GC सबसे अनुपयुक्त समय पर शुरू हो सकता है — जब आपका कोड कोई महत्वपूर्ण अनुरोध संसाधित कर रहा हो या गेम में कोई फ्रेम रेंडर कर रहा हो।
  • \n
  • मेमोरी ओवरहेड। GC को अक्सर अपने काम के लिए अतिरिक्त मेमोरी की आवश्यकता होती है।
  • \n
  • रीयल-टाइम सिस्टम में जटिलता। ऑपरेटिंग सिस्टम, ड्राइवर या एम्बेडेड डिवाइस में GC के ठहराव अस्वीकार्य हैं।
  • \n
\n\n

Rust एक मौलिक रूप से भिन्न दृष्टिकोण प्रस्तुत करता है। गार्बेज कलेक्टर के बजाय, स्वामित्व प्रणाली (ownership) का उपयोग किया जाता है, जो संकलन चरण पर काम करती है। कंपाइलर स्वयं तय करता है कि मेमोरी कब मुक्त की जानी चाहिए, और वह इसे बिना किसी runtime-ओवरहेड के करता है। आइए समझते हैं कि यह कैसे काम करता है।

\n\n

स्वामित्व प्रणाली (Ownership) — मेमोरी प्रबंधन का आधार

\n\n

Rust में, प्रत्येक मान का ठीक एक मालिक होता है — वह चर जिससे यह मान संबंधित है। जब मालिक दायरे (scope) से बाहर हो जाता है, तो मेमोरी स्वचालित रूप से मुक्त हो जाती है। कोई गार्बेज कलेक्टर नहीं, कोई संदर्भ गणना नहीं — केवल कंपाइलर और सख्त नियम।

\n\n

Rust में स्वामित्व के नियम

\n\n

यहाँ तीन मुख्य नियम हैं, जिन्हें कंपाइलर संकलन चरण पर जाँचता है:

\n\n
    \n
  • Rust में प्रत्येक मान का एक मालिक होता है।
  • \n
  • जब मालिक दायरे से बाहर होता है, तो मान हटा दिया जाता है (drop)।
  • \n
  • मान को किसी अन्य मालिक को स्थानांतरित (move) किया जा सकता है या उधार (borrow) दिया जा सकता है।
  • \n
\n\n
fn main() {\n    let s1 = String::from("Hello"); // s1 — स्ट्रिंग का मालिक\n    let s2 = s1;                     // स्वामित्व s2 को स्थानांतरित हो जाता है (move)\n    // println!("{}", s1);           // त्रुटि! s1 अब स्ट्रिंग का मालिक नहीं है\n    println!("{}", s2);             // ठीक: s2 नया मालिक है\n} // यहाँ s1 और s2 दोनों दायरे से बाहर हो जाते हैं,\n  // लेकिन मेमोरी केवल एक बार मुक्त होती है — s2 के लिए
\n\n

Python या Java में, आप ऑब्जेक्ट पर केवल एक और संदर्भ बनाते, और GC बाद में इससे निपटता। Rust में — कोई आश्चर्य नहीं: कंपाइलर गारंटी देता है कि मेमोरी ठीक एक बार मुक्त होगी।

\n\n

उधार लेना (Borrowing) — स्वामित्व स्थानांतरित किए बिना डेटा का उपयोग कैसे करें

\n\n

अक्सर हमें मालिक से डेटा लिए बिना अस्थायी रूप से डेटा तक पहुँच "उधार" लेने की आवश्यकता होती है। इसके लिए Rust में संदर्भ (references) हैं। वे दो प्रकार के होते हैं:

\n\n
    \n
  • अपरिवर्तनीय संदर्भ (&T): डेटा पढ़ा जा सकता है, लेकिन बदला नहीं जा सकता।
  • \n
  • परिवर्तनीय संदर्भ (&mut T): पढ़ा और बदला जा सकता है, लेकिन केवल तभी जब कोई अन्य सक्रिय संदर्भ न हों।
  • \n
\n\n
fn main() {\n    let mut text = String::from("Rust");\n    \n    let r1 = &text;     // अपरिवर्तनीय संदर्भ\n    let r2 = &text;     // एक और अपरिवर्तनीय — संभव है\n    println!("{} {}", r1, r2);\n    \n    let r3 = &mut text; // परिवर्तनीय संदर्भ — काम करता है, क्योंकि r1 और r2 अब उपयोग नहीं हो रहे\n    r3.push_str(" rocks!");\n    println!("{}", r3);\n    \n    // लेकिन ऐसा नहीं कर सकते:\n    // let r1 = &text;\n    // let r3 = &mut text; // त्रुटि! एक साथ परिवर्तनीय और अपरिवर्तनीय संदर्भ नहीं हो सकते\n}
\n\n

Rust कंपाइलर केवल एक स्थैतिक विश्लेषक नहीं है, यह एक सख्त लेकिन निष्पक्ष शिक्षक है। यह आपको अपने पैर में गोली मारने नहीं देगा। यदि आप अपरिवर्तनीय संदर्भ होने पर परिवर्तनीय संदर्भ बनाने का प्रयास करते हैं — तो आपको संकलन त्रुटि मिलेगी। यही borrow checker का काम है — वह तंत्र जो

ब्लॉग

पुस्तक अनुशंसाएँ