तुम सही हो। आपके द्वारा वर्णित कचरा संग्रह का विशिष्ट रूप " संदर्भ गणना " कहलाता है । जिस तरह से यह काम करता है (सबसे सरल मामले में, संदर्भ की गिनती के अधिकांश आधुनिक कार्यान्वयन वास्तव में काफी अलग तरीके से लागू होते हैं), इस तरह दिखता है:
- जब भी किसी ऑब्जेक्ट का संदर्भ जोड़ा जाता है (जैसे कि यह एक चर या एक क्षेत्र को सौंपा जाता है, विधि को पारित किया जाता है, और इसी तरह), इसकी संदर्भ संख्या 1 से बढ़ जाती है
- जब भी किसी ऑब्जेक्ट का संदर्भ हटा दिया जाता है (विधि वापस आती है, तो चर दायरे से बाहर हो जाता है, फ़ील्ड को फिर से किसी भिन्न ऑब्जेक्ट को सौंपा जाता है या जिस ऑब्जेक्ट में फ़ील्ड स्वयं कचरा एकत्र हो जाता है), संदर्भ संख्या 1 से कम हो जाती है
- जैसे ही संदर्भ संख्या 0 से टकराती है, वस्तु का अधिक संदर्भ नहीं होता है, जिसका अर्थ है कि कोई भी इसका उपयोग नहीं कर सकता है, इसलिए यह कचरा है और इसे एकत्र किया जा सकता है
और इस साधारण रणनीति में आपके द्वारा बताई गई समस्या है: यदि A, B और B का संदर्भ A बताता है, तो उनके दोनों संदर्भ मायने कभी 1 से कम नहीं हो सकते हैं , जिसका अर्थ है कि वे कभी एकत्रित नहीं होंगे।
इस समस्या से निपटने के चार तरीके हैं:
- अनदेखी करो इसे। यदि आपके पास पर्याप्त मेमोरी है, तो आपके चक्र छोटे और अनूठे हैं और आपका रनटाइम छोटा है, हो सकता है कि आप बस साइकिल एकत्र न करने से दूर हो सकते हैं। शेल स्क्रिप्ट इंटरप्रेटर के बारे में सोचें: शेल स्क्रिप्ट आमतौर पर केवल कुछ सेकंड के लिए चलती हैं और बहुत मेमोरी आवंटित नहीं करती हैं।
- अपने संदर्भ की गिनती करने वाले कचरा संग्रहकर्ता को किसी अन्य कचरा संग्राहक के साथ मिलाएं, जिसमें चक्र की समस्या नहीं है। CPython ऐसा करता है, उदाहरण के लिए: CPython में मुख्य कचरा संग्रहकर्ता एक संदर्भ गणना कलेक्टर है, लेकिन समय-समय पर साइकिल को इकट्ठा करने के लिए एक ट्रेसिंग कचरा संग्रहकर्ता चलाया जाता है।
- चक्रों का पता लगाएं। दुर्भाग्य से, एक ग्राफ में चक्रों का पता लगाना एक महंगा ऑपरेशन है। विशेष रूप से, इसके लिए बहुत अधिक ओवरहेड की आवश्यकता होती है जो एक ट्रेसिंग कलेक्टर होता है, इसलिए आप बस उन में से एक का उपयोग कर सकते हैं।
- एल्गोरिथ्म को उस तरह से लागू न करें जो आप और मैं करेंगे: 1970 के दशक के बाद से, ऐसे कई रोचक एल्गोरिदम विकसित किए गए हैं जो एक ही ऑपरेशन में चक्र का पता लगाने और संदर्भ की गिनती को एक चतुर तरीके से जोड़ते हैं जो कि उन्हें करने की तुलना में काफी सस्ता है। दोनों अलग या एक अनुरेखण कलेक्टर कर रही है।
वैसे, एक कचरा कलेक्टर को लागू करने का दूसरा प्रमुख तरीका (और मैंने पहले ही उस पर कुछ समय पहले संकेत दिया है) ट्रेस कर रहा है । एक ट्रेसिंग कलेक्टर रीचैबिलिटी की अवधारणा पर आधारित है । आप कुछ रूट सेट के साथ शुरू करते हैं जो आपको पता है कि हमेशा उपलब्ध है (वैश्विक स्थिरांक, उदाहरण के लिए, या Object
वर्ग, वर्तमान शाब्दिक गुंजाइश, वर्तमान स्टैक फ्रेम) और वहां से आप सभी वस्तुओं को ट्रेस करते हैं जो रूट सेट से पहुंच योग्य हैं, फिर जब तक आपके पास ट्रांज़िट बंद नहीं हो जाता, तब तक सभी ऑब्जेक्ट्स जो रूट सेट से पहुंच योग्य हैं, इत्यादि। सब कुछ जो उस बंद में नहीं है वह कचरा है।
चूँकि एक चक्र केवल अपने भीतर ही उपलब्ध होता है, लेकिन रूट सेट से उपलब्ध नहीं होता है, इसे एकत्र किया जाएगा।