संक्षेप में
कचरा संग्रहण करने वालों को अंतिम रूप देना कोई साधारण मामला नहीं है। संदर्भ गिनती जीसी के साथ उपयोग करना आसान है, लेकिन जीसी का यह परिवार अक्सर अधूरा है, जिससे कुछ वस्तुओं और संरचनाओं के विनाश और अंतिम रूप से स्पष्ट ट्रिगरिंग द्वारा स्मृति लीक की भरपाई की जा सकती है। ट्रेसिंग कचरा संग्राहक अधिक प्रभावी होते हैं, लेकिन वे ऑब्जेक्ट को अंतिम रूप देने और नष्ट करने के लिए पहचानना बहुत कठिन बनाते हैं, क्योंकि अप्रयुक्त मेमोरी की पहचान करने के लिए, इस प्रकार अधिक जटिल प्रबंधन की आवश्यकता होती है, समय और स्थान की लागत के साथ, और कचरे की जटिलता में। कार्यान्वयन।
परिचय
मैं मानता हूं कि आप जो पूछ रहे हैं वह यह है कि कचरा एकत्र करने वाली भाषाएं कचरा संग्रहण प्रक्रिया के भीतर विनाश / अंतिमकरण को स्वचालित रूप से क्यों नहीं संभालती हैं, जैसा कि टिप्पणी से संकेत मिलता है:
मुझे यह बहुत कमी लगती है कि ये भाषाएं स्मृति को केवल प्रबंधन के लायक संसाधन मानती हैं। सॉकेट्स, फ़ाइल हैंडल, एप्लिकेशन स्टेट्स के बारे में क्या?
मैं स्वीकृत से असहमत हूं kdbanman द्वारा दिए गए गए जवाब से हूं । हालांकि कहा गया तथ्य अधिकांशतः सही हैं, हालाँकि संदर्भ गणना के प्रति दृढ़ता से पक्षपाती हैं, मुझे विश्वास नहीं है कि वे प्रश्न में शिकायत की गई स्थिति को ठीक से समझाते हैं।
मुझे विश्वास नहीं है कि उस उत्तर में विकसित शब्दावली एक मुद्दा है, और यह चीजों को भ्रमित करने की अधिक संभावना है। वास्तव में, जैसा कि प्रस्तुत किया गया है, शब्दावली अधिकतर प्रक्रियाओं के सक्रिय होने के तरीके से निर्धारित होती है कि वे क्या करते हैं। मुद्दा यह है कि सभी मामलों में, किसी क्लीनअप प्रक्रिया के साथ किसी वस्तु की आवश्यकता को अंतिम रूप देने की आवश्यकता नहीं है और जो भी संसाधनों का उपयोग किया गया है, उन्हें मुक्त करने के लिए, स्मृति उनमें से केवल एक है। आदर्श रूप से, यह सब तब स्वचालित रूप से किया जाना चाहिए जब ऑब्जेक्ट का उपयोग नहीं किया जाना है, एक कचरा कलेक्टर के माध्यम से। व्यवहार में, जीसी गायब हो सकता है या कमियां हो सकती हैं, और इसे अंतिम रूप देने और पुनर्स्मरण के कार्यक्रम द्वारा स्पष्ट ट्रिगर करने के लिए मुआवजा दिया जाता है।
कार्यक्रम द्वारा स्पष्ट ट्रिगेरिंग एक समस्या है क्योंकि यह प्रोग्रामिंग त्रुटियों का विश्लेषण करने के लिए कठिन अनुमति दे सकता है, जब एक वस्तु अभी भी उपयोग में स्पष्ट रूप से समाप्त हो रही है।
इसलिए संसाधनों को पुनः प्राप्त करने के लिए स्वचालित कचरा संग्रह पर भरोसा करना बेहतर है। लेकिन दो मुद्दे हैं:
कुछ कचरा संग्रह तकनीक स्मृति लीक की अनुमति देगी जो संसाधनों के पूर्ण पुनर्ग्रहण को रोकती हैं। यह अच्छी तरह से संदर्भ गिनती जीसी के लिए जाना जाता है, लेकिन अन्य जीसी तकनीकों के लिए प्रकट हो सकता है जब देखभाल के बिना कुछ डेटा संगठनों का उपयोग किया जाता है (बिंदु यहां चर्चा नहीं की गई है)।
जबकि जीसी तकनीक का उपयोग स्मृति संसाधनों की पहचान करने में अच्छा नहीं हो सकता है, इसमें निहित वस्तुओं को अंतिम रूप देना सरल नहीं हो सकता है, और यह इन वस्तुओं द्वारा उपयोग किए जाने वाले अन्य संसाधनों को पुनः प्राप्त करने की समस्या को जटिल करता है, जो अक्सर अंतिम रूप देने का उद्देश्य होता है।
अंत में, एक महत्वपूर्ण बिंदु अक्सर यह भूल जाता है कि जीसी चक्रों को किसी भी चीज से ट्रिगर किया जा सकता है, न कि केवल मेमोरी की कमी, यदि उचित हुक प्रदान किए जाते हैं और यदि जीसी चक्र की लागत इसके लायक मानी जाती है। इसलिए किसी भी तरह के संसाधन गायब होने पर, कुछ को मुक्त करने की उम्मीद में, जीसी शुरू करना पूरी तरह से ठीक है।
संदर्भ गिनती कचरा बीनने वाले
रेफरेंस काउंटिंग एक कमज़ोर कचरा इकट्ठा करने की तकनीक है , जिससे साइकिल ठीक से नहीं चल पाएगी। यह वास्तव में अप्रचलित संरचनाओं को नष्ट करने, और अन्य संसाधनों को पुनः प्राप्त करने पर कमजोर होगा क्योंकि यह स्मृति को पुनः प्राप्त करने में कमजोर है। लेकिन अंतिम रूप से उपयोग किया जा सकता है एक संदर्भ गिनती कचरा कलेक्टर (जीसी) के साथ सबसे अधिक आसानी से, क्योंकि एक रेफ-गिनती जीसी एक संरचना को फिर से बताता है जब इसकी रेफरी गिनती 0 से नीचे जाती है, जिस समय इसका पता अपने प्रकार के साथ एक साथ पता चलता है, या तो सांख्यिकीय रूप से। या गतिशील रूप से। इसलिए उचित फ़ाइनलीज़र लागू करने के बाद मेमोरी को पुनः प्राप्त करना संभव है, और सभी पॉइंटेड ऑब्जेक्ट्स पर संभवतः प्रक्रिया को कॉल करना संभव है (संभवतः अंतिम प्रक्रिया के माध्यम से)।
संक्षेप में, अंतिम रूप Ref Refing GC के साथ कार्यान्वित करना आसान है, लेकिन उस GC की "अपूर्णता" से पीड़ित है, वास्तव में परिपत्र संरचनाओं के कारण, ठीक उसी सीमा तक कि स्मृति पुनर्ग्रहण ग्रस्त है। दूसरे शब्दों में, रेफरेंस काउंट के साथ, मेमोरी ठीक उसी तरह से प्रबंधित होती है जैसे अन्य संसाधन जैसे सॉकेट्स, फाइल हैंडल आदि।
दरअसल, लूपिंग संरचनाओं को पुनः प्राप्त करने के लिए रेफ काउंट जीसी अक्षमता (सामान्य रूप से) को स्मृति रिसाव के रूप में देखा जा सकता है । मेमोरी लीक से बचने के लिए आप सभी GC की उम्मीद नहीं कर सकते। यह जीसी एल्गोरिदम पर निर्भर करता है, और प्रकार की संरचना की जानकारी गतिशील रूप से उपलब्ध है (उदाहरण के लिए
रूढ़िवादी जीसी में )।
कचरा बीनने वालों का पता लगाना
ऐसे लीक के बिना जीसी का अधिक शक्तिशाली परिवार, अनुरेखण परिवार है जो स्मृति के लाइव भागों की खोज करता है, अच्छी तरह से पहचाने गए रूट पॉइंटर्स से शुरू होता है। मेमोरी के सभी भाग जो इस ट्रेसिंग प्रक्रिया में नहीं आते हैं (जो कि वास्तव में विभिन्न तरीकों से विघटित हो सकते हैं, लेकिन मुझे सरल करना है) मेमोरी के अप्रयुक्त भाग हैं जिन्हें इस प्रकार से 1 पुनः प्राप्त किया जा सकता है । ये कलेक्टर सभी मेमोरी भागों को पुनः प्राप्त करेंगे जो अब प्रोग्राम द्वारा एक्सेस नहीं किए जा सकते हैं, चाहे वह कोई भी हो। यह परिपत्र संरचनाओं को पुनः प्राप्त करता है, और अधिक उन्नत जीसी इस प्रतिमान के कुछ भिन्नता पर आधारित होते हैं, कभी-कभी अत्यधिक परिष्कृत होते हैं। इसे कुछ मामलों में संदर्भ गिनती के साथ जोड़ा जा सकता है, और इसकी कमजोरियों के लिए क्षतिपूर्ति की जा सकती है।
एक समस्या यह है कि आपका कथन (प्रश्न के अंत में):
स्वचालित कचरा संग्रहण की पेशकश करने वाली भाषाएं ऑब्जेक्ट विनाश / अंतिमकरण का समर्थन करने के लिए प्रमुख उम्मीदवार लगती हैं क्योंकि वे 100% निश्चितता के साथ जानते हैं जब कोई वस्तु उपयोग में नहीं होती है।
कलेक्टरों को ट्रेस करने के लिए तकनीकी रूप से गलत है ।
जिसे 100% निश्चितता के साथ जाना जाता है वह यह है कि स्मृति के कौन से हिस्से अब उपयोग में नहीं हैं । (अधिक सटीक रूप से, यह कहा जाना चाहिए कि वे अब सुलभ नहीं हैं , क्योंकि कुछ भाग, जिन्हें अब प्रोग्राम के तर्क के अनुसार उपयोग नहीं किया जा सकता है, अभी भी उपयोग में माना जाता है यदि प्रोग्राम में अभी भी उनके लिए एक बेकार सूचक है डेटा।) लेकिन आगे की प्रक्रिया और उपयुक्त संरचनाओं को यह जानने की जरूरत है कि अप्रयुक्त वस्तुओं को मेमोरी के इन अप्रयुक्त हिस्सों में संग्रहीत किया जा सकता है । यह इस बात से निर्धारित नहीं किया जा सकता है कि प्रोग्राम के बारे में क्या पता है, क्योंकि प्रोग्राम अब मेमोरी के इन हिस्सों से जुड़ा नहीं है।
इस प्रकार कचरा संग्रह के पास होने के बाद, आपको उन मेमोरीज़ के टुकड़ों के साथ छोड़ दिया जाता है, जिनमें ऐसी वस्तुएँ होती हैं जो अब उपयोग में नहीं हैं, लेकिन यह जानने का कोई तरीका नहीं है कि इन वस्तुओं को सही अंतिम रूप देने के लिए क्या किया जाए। इसके अलावा, यदि ट्रेसिंग कलेक्टर मार्क-एंड-स्वीप प्रकार है, तो यह हो सकता है कि कुछ अंशों में ऐसी वस्तुएं हो सकती हैं जो पहले से पिछले जीसी पास में अंतिम रूप दे चुकी हैं, लेकिन विखंडन कारणों से इसका उपयोग नहीं किया गया था। हालाँकि इससे विस्तारित स्पष्ट टाइपिंग का उपयोग करके निपटा जा सकता है।
हालांकि एक साधारण कलेक्टर सिर्फ मेमोरी के इन टुकड़ों को पुनः प्राप्त करेगा, आगे की हलचल के बिना, अंतिमकरण के लिए उस अप्रयुक्त मेमोरी का पता लगाने के लिए एक विशिष्ट पास की आवश्यकता होती है, वहां मौजूद वस्तुओं की पहचान करें और अंतिमकरण प्रक्रियाओं को लागू करें। लेकिन इस तरह के अन्वेषण के लिए आवश्यक वस्तुओं के प्रकार का निर्धारण किया गया था, और यदि कोई हो, तो उचित निर्धारण को लागू करने के लिए भी प्रकार के निर्धारण की आवश्यकता होती है।
ताकि जीसी समय (अतिरिक्त पास) में अतिरिक्त लागत और संभवतः विभिन्न तकनीकों द्वारा उस पास के दौरान उचित प्रकार की जानकारी उपलब्ध हो सके। ये लागत महत्वपूर्ण हो सकती हैं क्योंकि एक व्यक्ति अक्सर केवल कुछ वस्तुओं को अंतिम रूप देना चाहेगा, जबकि समय और स्थान ओवरहेड सभी वस्तुओं की चिंता कर सकता है।
एक और बिंदु यह है कि समय और स्थान का उपरि कार्यक्रम कोड निष्पादन की चिंता कर सकता है, न कि केवल जीसी निष्पादन।
मैं विशिष्ट मुद्दों की ओर संकेत करते हुए अधिक सटीक उत्तर नहीं दे सकता, क्योंकि मैं आपके द्वारा सूचीबद्ध कई भाषाओं की बारीकियों को नहीं जानता। सी के मामले में, टाइपिंग एक बहुत ही मुश्किल मुद्दा है जो रूढ़िवादी कलेक्टरों के विकास की ओर ले जाता है। मेरा अनुमान है कि यह C ++ को भी प्रभावित करता है, लेकिन मैं C ++ का कोई विशेषज्ञ नहीं हूं। इस बात की पुष्टि हंस बोहेम ने की है जिन्होंने रूढ़िवादी जीसी पर बहुत शोध किया है। रूढ़िवादी जीसी व्यवस्थित रूप से सभी अप्रयुक्त मेमोरी को ठीक से पुनः प्राप्त नहीं कर सकता है क्योंकि इसमें डेटा पर सटीक प्रकार की जानकारी का अभाव हो सकता है। इसी कारण से, यह व्यवस्थित रूप से अंतिम रूप देने वाली प्रक्रियाओं को लागू करने में सक्षम नहीं होगा।
इसलिए, आप जो पूछ रहे हैं, वह करना संभव है, जैसा कि आप कुछ भाषाओं से जानते हैं। लेकिन यह मुफ्त में नहीं आता है। भाषा और इसके कार्यान्वयन पर निर्भर करते हुए, यह सुविधा का उपयोग न करने पर भी लागत में प्रवेश कर सकता है। इन मुद्दों को संबोधित करने के लिए विभिन्न तकनीकों और व्यापार-बंदों पर विचार किया जा सकता है, लेकिन यह एक उचित आकार के उत्तर के दायरे से परे है।
1 - यह ट्रेसिंग कलेक्शन की एक अमूर्त प्रस्तुति है (कॉपी और मार्क और स्वीप जीसी दोनों को शामिल करते हुए), चीजें ट्रेसिंग कलेक्टर के प्रकार के अनुसार अलग-अलग हो सकती हैं, और मेमोरी के अप्रयुक्त हिस्से की खोज अलग-अलग होती है, जो इस बात पर निर्भर करती है कि कॉपी या मार्क है या नहीं। झाडू का उपयोग किया जाता है।
finalize
/destroy
एक झूठ है? इसकी कोई गारंटी नहीं है कि इसे कभी भी निष्पादित किया जाएगा। और, भले ही, आप नहीं जानते कि कब (स्वचालित कचरा संग्रह दिया गया है), और यदि आवश्यक संदर्भ अभी भी है (यह पहले से ही एकत्र किया जा सकता है)। तो यह अन्य तरीकों से लगातार राज्य सुनिश्चित करने के लिए सुरक्षित है, और कोई प्रोग्रामर को ऐसा करने के लिए मजबूर करना चाह सकता है।