कचरा एकत्र करने वाली भाषाओं में वस्तु विध्वंसक प्रतिमान क्यों अनुपस्थित है?


27

कचरा एकत्र भाषा डिजाइन के आसपास के फैसलों में अंतर्दृष्टि की तलाश। शायद एक भाषा विशेषज्ञ मुझे बता सकता है? मैं एक C ++ बैकग्राउंड से आता हूं, इसलिए यह क्षेत्र मेरे लिए चौंकाने वाला है।

ऐसा लगता है कि रूबी, जावास्क्रिप्ट / ES6 / ES7, Actionscript, Lua, आदि OOPy वस्तु समर्थन के साथ लगभग सभी आधुनिक कचरा एकत्र भाषाओं पूरी तरह से विध्वंसक / अंतिम प्रतिमान को छोड़ देते हैं। अजगर अपनी class __del__()विधि के साथ केवल एक ही लगता है । ऐसा क्यों है? क्या स्वचालित कचरा संग्रह के साथ भाषाओं के भीतर कार्यात्मक / सैद्धांतिक सीमाएँ हैं जो वस्तुओं पर एक विध्वंसक / अंतिम विधि के प्रभावी कार्यान्वयन को रोकती हैं?

मुझे यह बहुत कमी लगती है कि ये भाषाएं स्मृति को केवल प्रबंधन के लायक संसाधन मानती हैं । सॉकेट्स, फ़ाइल हैंडल, एप्लिकेशन स्टेट्स के बारे में क्या? गैर-स्मृति संसाधनों और ऑब्जेक्ट को अंतिम रूप देने पर कस्टम लॉजिक को लागू करने की क्षमता के बिना, मुझे अपने एप्लिकेशन को कस्टम myObject.destroy()स्टाइल कॉल के साथ लिट करने की आवश्यकता है , क्लीनअप लॉजिक को मेरी "क्लास" के बाहर रखने, प्रयास किए गए एन्कैप्सुलेशन को तोड़ने, और मेरे प्रतिनिधि मानव संसाधन त्रुटि के कारण संसाधन लीक के लिए आवेदन स्वचालित रूप से gc द्वारा संभाला जा रहा है।

भाषा डिजाइन निर्णय क्या हैं जो इन भाषाओं को ले जाते हैं और ऑब्जेक्ट निपटान पर कस्टम तर्क को निष्पादित करने का कोई तरीका नहीं है? मुझे लगता है कि एक अच्छा कारण है। मैं उन तकनीकी और सैद्धांतिक निर्णयों को बेहतर ढंग से समझना चाहूंगा जिनके परिणामस्वरूप इन भाषाओं को ऑब्जेक्ट विनाश / अंतिमकरण के लिए समर्थन नहीं मिला।

अद्यतन करें:

शायद मेरे सवाल का जवाब देने का एक बेहतर तरीका:

एक भाषा में कस्टम इंस्टेंटेशन (निर्माणकर्ता) के साथ वर्ग या वर्ग जैसी संरचनाओं के साथ वस्तु उदाहरणों की अंतर्निहित अवधारणा क्यों होगी, फिर भी विनाश / अंतिम कार्यक्षमता को पूरी तरह से छोड़ देना चाहिए? स्वचालित कचरा संग्रहण की पेशकश करने वाली भाषाएं ऑब्जेक्ट विनाश / अंतिमकरण का समर्थन करने के लिए प्रमुख उम्मीदवार लगती हैं क्योंकि वे 100% निश्चितता के साथ जानते हैं जब कोई वस्तु उपयोग में नहीं होती है। फिर भी उन भाषाओं में से अधिकांश इसका समर्थन नहीं करती हैं।

मुझे नहीं लगता कि यह ऐसा मामला है जहां विध्वंसक को कभी नहीं बुलाया जा सकता है, क्योंकि यह एक कोर मेमोरी लीक होगी, जिसे बचने के लिए डिज़ाइन किया गया है। मैं एक संभावित तर्क को देख सकता हूं कि भविष्य में कुछ अनिश्चित समय तक विध्वंसक / अंतिम रूप से कॉल नहीं किया जा सकता है, लेकिन यह जावा या पायथन को कार्यक्षमता का समर्थन करने से नहीं रोकता है।

ऑब्जेक्ट फाइनल के किसी भी रूप का समर्थन नहीं करने के लिए मूल भाषा डिजाइन कारण क्या हैं?


9
हो सकता है क्योंकि finalize/ destroyएक झूठ है? इसकी कोई गारंटी नहीं है कि इसे कभी भी निष्पादित किया जाएगा। और, भले ही, आप नहीं जानते कि कब (स्वचालित कचरा संग्रह दिया गया है), और यदि आवश्यक संदर्भ अभी भी है (यह पहले से ही एकत्र किया जा सकता है)। तो यह अन्य तरीकों से लगातार राज्य सुनिश्चित करने के लिए सुरक्षित है, और कोई प्रोग्रामर को ऐसा करने के लिए मजबूर करना चाह सकता है।
राफेल

1
मुझे लगता है कि यह सवाल सीमावर्ती ऑफटॉपिक है। क्या हम जिस तरह का मनोरंजन करना चाहते हैं, यह एक प्रोग्रामिंग लैंग्वेज का प्रश्न है, या यह किसी साइट के लिए प्रोग्रामिंग की ओर उन्मुख है? कृपया वोट करें।
राफेल

14
यह पीएल डिजाइन में एक अच्छा सवाल है, चलो यह है।
बाउर

3
यह वास्तव में एक स्थिर / गतिशील अंतर नहीं है। कई स्थिर भाषाओं में अंतिम रूप नहीं होता है। वास्तव में, अल्पसंख्यकों में अंतिम रूप देने वाली भाषाएं नहीं हैं?
बॉयर

1
लगता है कि यहाँ कुछ सवाल है ... यदि आप शब्दों को थोड़ा और परिभाषित करें तो बेहतर होगा। जावा में अंत में एक ब्लॉक होता है जो ऑब्जेक्ट विनाश से नहीं बल्कि विधि से बाहर निकलता है। संसाधनों से निपटने के अन्य तरीके भी हैं। जावा में, एक कनेक्शन पूल उन कनेक्शनों से निपट सकता है जो अप्रयुक्त हो जाते हैं [x] समय के साथ और उन्हें पुनः प्राप्त करते हैं। सुरुचिपूर्ण नहीं है लेकिन यह काम करता है। आपके प्रश्न के उत्तर का एक हिस्सा यह है कि कचरा संग्रह लगभग एक nondeterministic है, तात्कालिक प्रक्रिया नहीं है और ऐसी वस्तुओं द्वारा संचालित नहीं किया जा रहा है जो किसी भी तरह से उपयोग नहीं की जा रही हैं, लेकिन स्मृति बाधाओं / छत द्वारा ट्रिगर किया जा रहा है।
vzn

जवाबों:


10

जिस पैटर्न के बारे में आप बात कर रहे हैं, जहां ऑब्जेक्ट्स अपने संसाधनों को साफ करना जानते हैं, तीन प्रासंगिक श्रेणियों में आते हैं। आइए conflate नहीं विनाशकर्ता साथ finalizers - केवल एक कचरा संग्रहण से संबंधित है:

  • Finalizer पैटर्न : सफाई प्रक्रिया स्वतः ही घोषित कर दिया, प्रोग्रामर द्वारा परिभाषित, स्वचालित रूप से कहा जाता है।

    कचरा बीनने वाले से निपटने से पहले फाइनल को स्वचालित रूप से कहा जाता है। यह शब्द लागू होता है यदि कचरा संग्रह एल्गोरिथ्म नियोजित वस्तु जीवन चक्र निर्धारित कर सकता है।

  • नाशक पैटर्न : सफाई प्रक्रिया स्वतः ही घोषित कर दिया, प्रोग्रामर द्वारा परिभाषित किया गया, वह अपने आप केवल कभी कभी कहा जाता है।

    स्टैक-आबंटित ऑब्जेक्ट्स के लिए विनाशकों को स्वचालित रूप से कहा जा सकता है (क्योंकि ऑब्जेक्ट जीवनकाल नियतात्मक है), लेकिन स्पष्ट रूप से ढेर-आवंटित ऑब्जेक्ट्स के लिए सभी संभावित निष्पादन पथों पर बुलाया जाना चाहिए (क्योंकि ऑब्जेक्ट लाइफटाइम नॉन्डेटेरमिनिस्टिक है)।

  • Disposer पैटर्न : सफाई विधि की घोषणा की, परिभाषित है, और प्रोग्रामर द्वारा कहा जाता है।

    प्रोग्रामर एक निपटान विधि बनाते हैं और इसे स्वयं कहते हैं - यह वह जगह है जहां आपका कस्टम myObject.destroy()तरीका गिरता है। यदि निपटान की आवश्यकता है, तो सभी संभावित निष्पादन मार्गों पर डिस्पोजर्स को बुलाया जाना चाहिए।

फाइनल करने वाले आप के लिए खोज रहे हैं।

फ़ाइज़राइज़र पैटर्न (जिस पैटर्न के बारे में आपका प्रश्न पूछ रहा है) एक कचरा संग्राहक द्वारा पारस्परिक पुनर्वसन के लिए सिस्टम संसाधनों (सॉकेट्स, फ़ाइल डिस्क्रिप्टर, आदि) के साथ वस्तुओं को जोड़ने का तंत्र है। लेकिन, फाइनल में मूल रूप से उपयोग में कचरा संग्रह एल्गोरिदम की दया पर हैं।

आपकी इस धारणा पर विचार करें:

स्वचालित कचरा संग्रहण की पेशकश करने वाली भाषाएँ ... 100% निश्चितता के साथ जानें जब कोई वस्तु अब उपयोग में नहीं है।

तकनीकी रूप से गलत (साभार, @babou)। कचरा संग्रह मूल रूप से स्मृति के बारे में है, न कि वस्तुओं के बारे में। यदि या जब एक संग्रह एल्गोरिथ्म को पता चलता है कि ऑब्जेक्ट की मेमोरी अब उपयोग में नहीं है, तो एल्गोरिथ्म पर निर्भर करता है और (संभवतया) आपकी वस्तुएं एक दूसरे को कैसे संदर्भित करती हैं। दो प्रकार के रनवे कचरा संग्रहकर्ताओं के बारे में बात करते हैं। बुनियादी तकनीकों में इन्हें बदलने और बढ़ाने के बहुत सारे तरीके हैं:

  1. ट्रेसिंग जीसी। ये मेमोरी को ट्रेस करते हैं, ऑब्जेक्ट को नहीं। जब तक ऐसा करने के लिए संवर्धित नहीं किया जाता है, वे स्मृति से वस्तुओं के संदर्भ को वापस नहीं रखते हैं। जब तक संवर्धित नहीं किया जाता है, इन GCs को पता नहीं चलेगा कि किसी वस्तु को अंतिम रूप कब दिया जा सकता है, भले ही वे जानते हों कि इसकी स्मृति अनुपलब्ध है। इसलिए, अंतिम कॉल की गारंटी नहीं है।

  2. संदर्भ गिनती जीसी । ये मेमोरी को ट्रैक करने के लिए ऑब्जेक्ट का उपयोग करते हैं। वे संदर्भ के एक निर्देशित ग्राफ के साथ वस्तु की पुनरावृत्ति को मॉडल करते हैं। यदि आपके ऑब्जेक्ट संदर्भ ग्राफ में एक चक्र है, तो चक्र में सभी वस्तुओं का कभी भी उनका अंतिम नाम नहीं होगा (जब तक कि कार्यक्रम समाप्ति, स्पष्ट रूप से)। फिर, फाइनल कॉल की गारंटी नहीं है।

TLDR

कचरा संग्रह कठिन और विविध है। कार्यक्रम समाप्ति से पहले एक अंतिम कॉल की गारंटी नहीं दी जा सकती।


आप सही हैं कि यह स्थिर वी गतिशील नहीं है। यह कचरा एकत्र करने वाली भाषाओं के साथ एक मुद्दा है। कचरा संग्रहण एक जटिल समस्या है और शायद प्राथमिक कारण है क्योंकि विचार करने के लिए कई किनारे मामले हैं (जैसे कि क्या होता है यदि तर्क के finalize()कारण वस्तु को फिर से संदर्भित किया जा रहा है?)। हालाँकि, प्रोग्राम समाप्ति से पहले बुलाए जा रहे फाइनल की गारंटी देने में असमर्थ होना जावा को समर्थन करने से नहीं रोकता है। आपके उत्तर को गलत नहीं कहना, बस अधूरा है। फिर भी बहुत अच्छी पोस्ट। धन्यवाद।
dbcb

प्रतिक्रिया के लिए धन्यवाद। यहां मेरा उत्तर पूरा करने का प्रयास किया गया है: अंतिम रूप से अंतिम रूप से चूकने से, एक भाषा अपने उपयोगकर्ताओं को अपने संसाधनों का प्रबंधन करने के लिए मजबूर करती है। कई प्रकार की समस्याओं के लिए, यह संभवतः एक नुकसान है। व्यक्तिगत रूप से, मैं जावा की पसंद को पसंद करता हूं, क्योंकि मेरे पास फाइनल करने वालों की शक्ति है और मुझे अपने स्वयं के डिस्पोजर को लिखने और उपयोग करने से कुछ भी नहीं रोक रहा है। जावा का कहना है, "अरे, प्रोग्रामर। आप बेवकूफ नहीं हैं, इसलिए यहां एक फाइनल है। बस सावधान रहें।"
kdbanman

1
यह दर्शाने के लिए मेरा मूल प्रश्न अपडेट किया गया है कि यह कचरा एकत्रित भाषाओं से संबंधित है। आपके उत्तर को स्वीकार करना। जवाब देने में व़क्त लेने के लिए शुक्रिया।
dbcb

मदद करने के लिए खुश। क्या मेरी टिप्पणी ने मेरे जवाब को स्पष्ट कर दिया है?
केदबन

2
यह अच्छा है। मेरे लिए, यहां असली जवाब यह है कि भाषाएं इसे लागू नहीं करना चाहती हैं क्योंकि कथित मूल्य कार्यक्षमता को लागू करने की समस्याओं से आगे नहीं बढ़ता है। यह असंभव नहीं है (जैसा कि जावा और पायथन प्रदर्शित करता है), लेकिन एक व्यापार बंद है जो कई भाषाओं को बनाने के लिए नहीं चुनते हैं।
dbcb

5

संक्षेप में

कचरा संग्रहण करने वालों को अंतिम रूप देना कोई साधारण मामला नहीं है। संदर्भ गिनती जीसी के साथ उपयोग करना आसान है, लेकिन जीसी का यह परिवार अक्सर अधूरा है, जिससे कुछ वस्तुओं और संरचनाओं के विनाश और अंतिम रूप से स्पष्ट ट्रिगरिंग द्वारा स्मृति लीक की भरपाई की जा सकती है। ट्रेसिंग कचरा संग्राहक अधिक प्रभावी होते हैं, लेकिन वे ऑब्जेक्ट को अंतिम रूप देने और नष्ट करने के लिए पहचानना बहुत कठिन बनाते हैं, क्योंकि अप्रयुक्त मेमोरी की पहचान करने के लिए, इस प्रकार अधिक जटिल प्रबंधन की आवश्यकता होती है, समय और स्थान की लागत के साथ, और कचरे की जटिलता में। कार्यान्वयन।

परिचय

मैं मानता हूं कि आप जो पूछ रहे हैं वह यह है कि कचरा एकत्र करने वाली भाषाएं कचरा संग्रहण प्रक्रिया के भीतर विनाश / अंतिमकरण को स्वचालित रूप से क्यों नहीं संभालती हैं, जैसा कि टिप्पणी से संकेत मिलता है:

मुझे यह बहुत कमी लगती है कि ये भाषाएं स्मृति को केवल प्रबंधन के लायक संसाधन मानती हैं। सॉकेट्स, फ़ाइल हैंडल, एप्लिकेशन स्टेट्स के बारे में क्या?

मैं स्वीकृत से असहमत हूं kdbanman द्वारा दिए गए गए जवाब से हूं । हालांकि कहा गया तथ्य अधिकांशतः सही हैं, हालाँकि संदर्भ गणना के प्रति दृढ़ता से पक्षपाती हैं, मुझे विश्वास नहीं है कि वे प्रश्न में शिकायत की गई स्थिति को ठीक से समझाते हैं।

मुझे विश्वास नहीं है कि उस उत्तर में विकसित शब्दावली एक मुद्दा है, और यह चीजों को भ्रमित करने की अधिक संभावना है। वास्तव में, जैसा कि प्रस्तुत किया गया है, शब्दावली अधिकतर प्रक्रियाओं के सक्रिय होने के तरीके से निर्धारित होती है कि वे क्या करते हैं। मुद्दा यह है कि सभी मामलों में, किसी क्लीनअप प्रक्रिया के साथ किसी वस्तु की आवश्यकता को अंतिम रूप देने की आवश्यकता नहीं है और जो भी संसाधनों का उपयोग किया गया है, उन्हें मुक्त करने के लिए, स्मृति उनमें से केवल एक है। आदर्श रूप से, यह सब तब स्वचालित रूप से किया जाना चाहिए जब ऑब्जेक्ट का उपयोग नहीं किया जाना है, एक कचरा कलेक्टर के माध्यम से। व्यवहार में, जीसी गायब हो सकता है या कमियां हो सकती हैं, और इसे अंतिम रूप देने और पुनर्स्मरण के कार्यक्रम द्वारा स्पष्ट ट्रिगर करने के लिए मुआवजा दिया जाता है।

कार्यक्रम द्वारा स्पष्ट ट्रिगेरिंग एक समस्या है क्योंकि यह प्रोग्रामिंग त्रुटियों का विश्लेषण करने के लिए कठिन अनुमति दे सकता है, जब एक वस्तु अभी भी उपयोग में स्पष्ट रूप से समाप्त हो रही है।

इसलिए संसाधनों को पुनः प्राप्त करने के लिए स्वचालित कचरा संग्रह पर भरोसा करना बेहतर है। लेकिन दो मुद्दे हैं:

  • कुछ कचरा संग्रह तकनीक स्मृति लीक की अनुमति देगी जो संसाधनों के पूर्ण पुनर्ग्रहण को रोकती हैं। यह अच्छी तरह से संदर्भ गिनती जीसी के लिए जाना जाता है, लेकिन अन्य जीसी तकनीकों के लिए प्रकट हो सकता है जब देखभाल के बिना कुछ डेटा संगठनों का उपयोग किया जाता है (बिंदु यहां चर्चा नहीं की गई है)।

  • जबकि जीसी तकनीक का उपयोग स्मृति संसाधनों की पहचान करने में अच्छा नहीं हो सकता है, इसमें निहित वस्तुओं को अंतिम रूप देना सरल नहीं हो सकता है, और यह इन वस्तुओं द्वारा उपयोग किए जाने वाले अन्य संसाधनों को पुनः प्राप्त करने की समस्या को जटिल करता है, जो अक्सर अंतिम रूप देने का उद्देश्य होता है।

अंत में, एक महत्वपूर्ण बिंदु अक्सर यह भूल जाता है कि जीसी चक्रों को किसी भी चीज से ट्रिगर किया जा सकता है, न कि केवल मेमोरी की कमी, यदि उचित हुक प्रदान किए जाते हैं और यदि जीसी चक्र की लागत इसके लायक मानी जाती है। इसलिए किसी भी तरह के संसाधन गायब होने पर, कुछ को मुक्त करने की उम्मीद में, जीसी शुरू करना पूरी तरह से ठीक है।

संदर्भ गिनती कचरा बीनने वाले

रेफरेंस काउंटिंग एक कमज़ोर कचरा इकट्ठा करने की तकनीक है , जिससे साइकिल ठीक से नहीं चल पाएगी। यह वास्तव में अप्रचलित संरचनाओं को नष्ट करने, और अन्य संसाधनों को पुनः प्राप्त करने पर कमजोर होगा क्योंकि यह स्मृति को पुनः प्राप्त करने में कमजोर है। लेकिन अंतिम रूप से उपयोग किया जा सकता है एक संदर्भ गिनती कचरा कलेक्टर (जीसी) के साथ सबसे अधिक आसानी से, क्योंकि एक रेफ-गिनती जीसी एक संरचना को फिर से बताता है जब इसकी रेफरी गिनती 0 से नीचे जाती है, जिस समय इसका पता अपने प्रकार के साथ एक साथ पता चलता है, या तो सांख्यिकीय रूप से। या गतिशील रूप से। इसलिए उचित फ़ाइनलीज़र लागू करने के बाद मेमोरी को पुनः प्राप्त करना संभव है, और सभी पॉइंटेड ऑब्जेक्ट्स पर संभवतः प्रक्रिया को कॉल करना संभव है (संभवतः अंतिम प्रक्रिया के माध्यम से)।

संक्षेप में, अंतिम रूप Ref Refing GC के साथ कार्यान्वित करना आसान है, लेकिन उस GC की "अपूर्णता" से पीड़ित है, वास्तव में परिपत्र संरचनाओं के कारण, ठीक उसी सीमा तक कि स्मृति पुनर्ग्रहण ग्रस्त है। दूसरे शब्दों में, रेफरेंस काउंट के साथ, मेमोरी ठीक उसी तरह से प्रबंधित होती है जैसे अन्य संसाधन जैसे सॉकेट्स, फाइल हैंडल आदि।

दरअसल, लूपिंग संरचनाओं को पुनः प्राप्त करने के लिए रेफ काउंट जीसी अक्षमता (सामान्य रूप से) को स्मृति रिसाव के रूप में देखा जा सकता है । मेमोरी लीक से बचने के लिए आप सभी GC की उम्मीद नहीं कर सकते। यह जीसी एल्गोरिदम पर निर्भर करता है, और प्रकार की संरचना की जानकारी गतिशील रूप से उपलब्ध है (उदाहरण के लिए रूढ़िवादी जीसी में )।

कचरा बीनने वालों का पता लगाना

ऐसे लीक के बिना जीसी का अधिक शक्तिशाली परिवार, अनुरेखण परिवार है जो स्मृति के लाइव भागों की खोज करता है, अच्छी तरह से पहचाने गए रूट पॉइंटर्स से शुरू होता है। मेमोरी के सभी भाग जो इस ट्रेसिंग प्रक्रिया में नहीं आते हैं (जो कि वास्तव में विभिन्न तरीकों से विघटित हो सकते हैं, लेकिन मुझे सरल करना है) मेमोरी के अप्रयुक्त भाग हैं जिन्हें इस प्रकार से 1 पुनः प्राप्त किया जा सकता है । ये कलेक्टर सभी मेमोरी भागों को पुनः प्राप्त करेंगे जो अब प्रोग्राम द्वारा एक्सेस नहीं किए जा सकते हैं, चाहे वह कोई भी हो। यह परिपत्र संरचनाओं को पुनः प्राप्त करता है, और अधिक उन्नत जीसी इस प्रतिमान के कुछ भिन्नता पर आधारित होते हैं, कभी-कभी अत्यधिक परिष्कृत होते हैं। इसे कुछ मामलों में संदर्भ गिनती के साथ जोड़ा जा सकता है, और इसकी कमजोरियों के लिए क्षतिपूर्ति की जा सकती है।

एक समस्या यह है कि आपका कथन (प्रश्न के अंत में):

स्वचालित कचरा संग्रहण की पेशकश करने वाली भाषाएं ऑब्जेक्ट विनाश / अंतिमकरण का समर्थन करने के लिए प्रमुख उम्मीदवार लगती हैं क्योंकि वे 100% निश्चितता के साथ जानते हैं जब कोई वस्तु उपयोग में नहीं होती है।

कलेक्टरों को ट्रेस करने के लिए तकनीकी रूप से गलत है

जिसे 100% निश्चितता के साथ जाना जाता है वह यह है कि स्मृति के कौन से हिस्से अब उपयोग में नहीं हैं । (अधिक सटीक रूप से, यह कहा जाना चाहिए कि वे अब सुलभ नहीं हैं , क्योंकि कुछ भाग, जिन्हें अब प्रोग्राम के तर्क के अनुसार उपयोग नहीं किया जा सकता है, अभी भी उपयोग में माना जाता है यदि प्रोग्राम में अभी भी उनके लिए एक बेकार सूचक है डेटा।) लेकिन आगे की प्रक्रिया और उपयुक्त संरचनाओं को यह जानने की जरूरत है कि अप्रयुक्त वस्तुओं को मेमोरी के इन अप्रयुक्त हिस्सों में संग्रहीत किया जा सकता है । यह इस बात से निर्धारित नहीं किया जा सकता है कि प्रोग्राम के बारे में क्या पता है, क्योंकि प्रोग्राम अब मेमोरी के इन हिस्सों से जुड़ा नहीं है।

इस प्रकार कचरा संग्रह के पास होने के बाद, आपको उन मेमोरीज़ के टुकड़ों के साथ छोड़ दिया जाता है, जिनमें ऐसी वस्तुएँ होती हैं जो अब उपयोग में नहीं हैं, लेकिन यह जानने का कोई तरीका नहीं है कि इन वस्तुओं को सही अंतिम रूप देने के लिए क्या किया जाए। इसके अलावा, यदि ट्रेसिंग कलेक्टर मार्क-एंड-स्वीप प्रकार है, तो यह हो सकता है कि कुछ अंशों में ऐसी वस्तुएं हो सकती हैं जो पहले से पिछले जीसी पास में अंतिम रूप दे चुकी हैं, लेकिन विखंडन कारणों से इसका उपयोग नहीं किया गया था। हालाँकि इससे विस्तारित स्पष्ट टाइपिंग का उपयोग करके निपटा जा सकता है।

हालांकि एक साधारण कलेक्टर सिर्फ मेमोरी के इन टुकड़ों को पुनः प्राप्त करेगा, आगे की हलचल के बिना, अंतिमकरण के लिए उस अप्रयुक्त मेमोरी का पता लगाने के लिए एक विशिष्ट पास की आवश्यकता होती है, वहां मौजूद वस्तुओं की पहचान करें और अंतिमकरण प्रक्रियाओं को लागू करें। लेकिन इस तरह के अन्वेषण के लिए आवश्यक वस्तुओं के प्रकार का निर्धारण किया गया था, और यदि कोई हो, तो उचित निर्धारण को लागू करने के लिए भी प्रकार के निर्धारण की आवश्यकता होती है।

ताकि जीसी समय (अतिरिक्त पास) में अतिरिक्त लागत और संभवतः विभिन्न तकनीकों द्वारा उस पास के दौरान उचित प्रकार की जानकारी उपलब्ध हो सके। ये लागत महत्वपूर्ण हो सकती हैं क्योंकि एक व्यक्ति अक्सर केवल कुछ वस्तुओं को अंतिम रूप देना चाहेगा, जबकि समय और स्थान ओवरहेड सभी वस्तुओं की चिंता कर सकता है।

एक और बिंदु यह है कि समय और स्थान का उपरि कार्यक्रम कोड निष्पादन की चिंता कर सकता है, न कि केवल जीसी निष्पादन।

मैं विशिष्ट मुद्दों की ओर संकेत करते हुए अधिक सटीक उत्तर नहीं दे सकता, क्योंकि मैं आपके द्वारा सूचीबद्ध कई भाषाओं की बारीकियों को नहीं जानता। सी के मामले में, टाइपिंग एक बहुत ही मुश्किल मुद्दा है जो रूढ़िवादी कलेक्टरों के विकास की ओर ले जाता है। मेरा अनुमान है कि यह C ++ को भी प्रभावित करता है, लेकिन मैं C ++ का कोई विशेषज्ञ नहीं हूं। इस बात की पुष्टि हंस बोहेम ने की है जिन्होंने रूढ़िवादी जीसी पर बहुत शोध किया है। रूढ़िवादी जीसी व्यवस्थित रूप से सभी अप्रयुक्त मेमोरी को ठीक से पुनः प्राप्त नहीं कर सकता है क्योंकि इसमें डेटा पर सटीक प्रकार की जानकारी का अभाव हो सकता है। इसी कारण से, यह व्यवस्थित रूप से अंतिम रूप देने वाली प्रक्रियाओं को लागू करने में सक्षम नहीं होगा।

इसलिए, आप जो पूछ रहे हैं, वह करना संभव है, जैसा कि आप कुछ भाषाओं से जानते हैं। लेकिन यह मुफ्त में नहीं आता है। भाषा और इसके कार्यान्वयन पर निर्भर करते हुए, यह सुविधा का उपयोग न करने पर भी लागत में प्रवेश कर सकता है। इन मुद्दों को संबोधित करने के लिए विभिन्न तकनीकों और व्यापार-बंदों पर विचार किया जा सकता है, लेकिन यह एक उचित आकार के उत्तर के दायरे से परे है।

1 - यह ट्रेसिंग कलेक्शन की एक अमूर्त प्रस्तुति है (कॉपी और मार्क और स्वीप जीसी दोनों को शामिल करते हुए), चीजें ट्रेसिंग कलेक्टर के प्रकार के अनुसार अलग-अलग हो सकती हैं, और मेमोरी के अप्रयुक्त हिस्से की खोज अलग-अलग होती है, जो इस बात पर निर्भर करती है कि कॉपी या मार्क है या नहीं। झाडू का उपयोग किया जाता है।


आप कचरा संग्रहण पर कई शानदार विवरण देते हैं। हालाँकि, आपका जवाब वास्तव में मेरा असहमत नहीं है - आपका सार और मेरा TLDR अनिवार्य रूप से एक ही बात कह रहा है। और इसके लायक क्या है, मेरा जवाब उदाहरण के रूप में संदर्भ गिनती जीसी का उपयोग करता है, न कि "मजबूत पूर्वाग्रह"।
kdbanman

अधिक अच्छी तरह से पढ़ने के बाद, मैं असहमति देखता हूं। मैं तदनुसार संपादित करूँगा। इसके अलावा, मेरी शब्दावली असंदिग्ध थी। प्रश्न फाइनली और डिस्ट्रक्टर्स का सामना कर रहा था और यहां तक ​​कि एक ही सांस में डिस्पोजर्स का भी उल्लेख किया गया था। सही शब्दों का प्रसार करने के लिए इसके लायक है।
kdbanman

@kdbanman कठिनाई यह थी कि मैं आप दोनों को संबोधित कर रहा था, क्योंकि आपका उत्तर संदर्भ के रूप में था। आप परिगणना उदाहरण के रूप में रेफरी गिनती का उपयोग नहीं कर सकते क्योंकि यह कमजोर जीसी है, शायद ही कभी भाषाओं में इस्तेमाल किया जाता है (ओपी द्वारा उद्धृत भाषाओं की जांच करें), जिसके लिए फाइनल जोड़ना वास्तव में आसान होगा (लेकिन सीमित उपयोग के साथ)। ट्रेसिंग कलेक्टर लगभग हमेशा उपयोग किए जाते हैं। लेकिन अंतिम रूप से उन पर हुक लगाना मुश्किल है, क्योंकि मरने वाली वस्तुओं का पता नहीं चलता है (कथन के विपरीत जिसे आप सही मानते हैं)। स्थैतिक और गतिशील टाइपिंग के बीच अंतर अप्रासंगिक है, डेटा स्टोर के गतिशील टाइपिंग द्वारा आवश्यक है।
बबौ

@kdbanman शब्दावली के बारे में, यह सामान्य रूप से उपयोगी है, क्योंकि यह विभिन्न स्थितियों के अनुरूप है। लेकिन यहां यह मदद नहीं करता है, क्योंकि सवाल जीसी को अंतिम रूप देने के बारे में है। मूल जीसी केवल विनाश करने के लिए माना जाता है। क्या जरूरत है एक शब्दावली जो भेद करती है getting memory recycled, जिसे मैं कॉल करता हूं reclamation, और इससे पहले कुछ सफाई करता हूं , जैसे कि अन्य संसाधनों को पुनः प्राप्त करना या कुछ ऑब्जेक्ट तालिकाओं को अपडेट करना, जिन्हें मैं कहता हूं finalization। ये मुझे प्रासंगिक मुद्दे लग रहे थे, लेकिन मुझे आपकी शब्दावली में एक बिंदु याद आ गया, जो मेरे लिए नया था।
बबौ

1
धन्यवाद @kdbanman, babou। अच्छी चर्चा। मुझे लगता है कि आपके दोनों पोस्ट समान बिंदुओं को कवर करते हैं। जैसा कि आप दोनों बताते हैं, मूल मुद्दा भाषा के रनटाइम में नियोजित कचरा कलेक्टर की श्रेणी प्रतीत होता है। मुझे यह लेख मिला , जो मेरे लिए कुछ भ्रांतियों को दूर करता है। ऐसा लगता है कि अधिक मजबूत जीकेएस केवल निम्न स्तर की कच्ची मेमोरी को संभालती है, जो उच्च स्तर की वस्तु प्रकार अपारदर्शी को जीसी तक पहुंचाती है। मेमोरी इंटर्नल के ज्ञान के बिना, जीसी वस्तुओं को नष्ट नहीं कर सकता है। जो आपका निष्कर्ष लगता है।
dbcb

4

ऑब्जेक्ट विध्वंसक पैटर्न सिस्टम प्रोग्रामिंग में त्रुटि से निपटने के लिए मौलिक है, लेकिन कचरा संग्रह से इसका कोई लेना-देना नहीं है। इसके बजाय, इसका मिलान जीवनकाल के दायरे में करना है, और इसे किसी भी भाषा में लागू / उपयोग किया जा सकता है जिसमें प्रथम श्रेणी के कार्य हैं।

उदाहरण (स्यूडोकोड)। मान लीजिए कि आपके पास एक "कच्ची फ़ाइल" प्रकार है, जैसे कि पॉज़िक्स फ़ाइल विवरणक प्रकार। चार मौलिक संचालन कर रहे हैं, , open(), close(), ।read() write()आप एक "सुरक्षित" फ़ाइल प्रकार को लागू करना चाहेंगे जो हमेशा स्वयं के बाद साफ हो। (यानी, एक स्वचालित निर्माता और विध्वंसक है।)

मुझे लगता है कि हमारी भाषा के पास अपवाद के साथ हैंडलिंग है throw, tryऔर finally(बिना किसी अपवाद के संभालती भाषा में आप एक अनुशासन स्थापित कर सकते हैं जहां आपके प्रकार का उपयोगकर्ता त्रुटि को इंगित करने के लिए एक विशेष मान लौटाता है।)

आप एक फ़ंक्शन सेट करते हैं जो एक फ़ंक्शन को स्वीकार करता है जो काम करता है। कार्यकर्ता फ़ंक्शन एक तर्क ("सुरक्षित" फ़ाइल के लिए एक हैंडल) को स्वीकार करता है।

with_file_opened_for_read (string:   filename,
                           function: worker_function(safe_file f)):
  raw_file rf = open(filename, O_RDONLY)
  if rf == error:
    throw File_Open_Error

  try:
    worker_function(rf)
  finally:
    close(rf)

तुम भी के कार्यान्वयन प्रदान read()और write()के लिए safe_file(कि सिर्फ फोन raw_file read()और write())। अब उपयोगकर्ता इस safe_fileप्रकार का उपयोग करता है :

...
with_file_opened_for_read ("myfile.txt",
                           anonymous_function(safe_file f):
                             mytext = read(f)
                             ... (including perhaps throwing an error)
                          )

एक सी ++ विध्वंसक वास्तव में एक try-finallyब्लॉक के लिए सिंटैक्टिक चीनी है । बहुत सब मैंने यहाँ किया है safe_fileएक निर्माता और विध्वंसक के साथ एक C ++ वर्ग में परिवर्तित क्या संकलित होगा। ध्यान दें कि C ++ के पास finallyइसके अपवादों के लिए नहीं है, विशेष रूप से क्योंकि स्ट्रॉस्ट्रुप ने महसूस किया कि एक स्पष्ट विध्वंसक का उपयोग करना बेहतर ढंग से किया गया था (और भाषा के अनाम कार्यों के पहले उन्होंने इसे भाषा में पेश किया था)।

(यह उन तरीकों में से एक का एक सरलीकरण है जो लोग कई सालों से लिस्प जैसी भाषाओं में त्रुटि से निपटने में कर रहे हैं। मुझे लगता है कि मैं पहली बार 1980 के दशक या 1990 के दशक की शुरुआत में इसमें भाग गया था, लेकिन मुझे याद नहीं है कि कहां है।)


यह C ++ में स्टैक आधारित डिस्ट्रक्टर पैटर्न के आंतरिक विवरणों का वर्णन करता है, लेकिन यह नहीं बताता है कि क्यों एक कचरा एकत्र भाषा ऐसी कार्यक्षमता को लागू नहीं करेगी। आप सही हो सकते हैं कि इसका कचरा संग्रह से कोई लेना-देना नहीं है, लेकिन यह सामान्य वस्तु विनाश / अंतिमकरण से संबंधित है, जो कचरा एकत्र भाषाओं में मुश्किल या अक्षम प्रतीत होता है। इसलिए यदि सामान्य विनाश का समर्थन नहीं किया जाता है, तो स्टैक आधारित विनाश को भी छोड़ दिया जाता है।
dbcb

जैसा कि मैंने शुरुआत में कहा था: कोई भी कचरा एकत्र की गई भाषा जिसमें प्रथम श्रेणी के कार्य होते हैं (या प्रथम श्रेणी के कार्यों का कुछ सन्निकटन) आपको "बुलेट प्रूफ" इंटरफेस प्रदान करने की क्षमता प्रदान करता है जैसे safe_fileऔर with_file_opened_for_readएक वस्तु जो अपने आप बंद हो जाती है जब वह दायरे से बाहर हो जाती है )। यह महत्वपूर्ण बात है, कि इसमें समान सिंटैक्स नहीं है क्योंकि निर्माता अप्रासंगिक हैं। लिस्प, स्कीम, जावा, स्काला, गो, हास्केल, रस्ट, जावास्क्रिप्ट, क्लोजर सभी पर्याप्त प्रथम श्रेणी के कार्यों का समर्थन करते हैं, इसलिए उन्हें समान उपयोगी सुविधा प्रदान करने के लिए विनाशकों की आवश्यकता नहीं होती है।
भटकना तर्क

मुझे लगता है कि मैं देख रहा हूं कि आप क्या कह रहे हैं। चूँकि भाषाएं मूल रूप से विध्वंसक-जैसी कार्यक्षमता को लागू करने के लिए मूल बिल्डिंग ब्लॉक्स (कोशिश / पकड़ / अंत में, प्रथम श्रेणी के कार्य आदि) प्रदान करती हैं, इसलिए उन्हें विध्वंसक की आवश्यकता नहीं होती है? मैं कुछ भाषाओं को सरलता के कारणों से ले सकता था। हालाँकि, ऐसा लगता नहीं है कि सूचीबद्ध सभी भाषाओं के लिए प्राथमिक कारण है, लेकिन शायद यही है। शायद मैं सिर्फ विशाल अल्पसंख्यक में हूं जो C ++ विध्वंसक को प्यार करता है और कोई और वास्तव में परवाह नहीं करता है, जो बहुत अच्छी तरह से यही कारण हो सकता है कि अधिकांश भाषाएं विध्वंसक को लागू नहीं करती हैं। वे सिर्फ परवाह नहीं करते।
dbcb

2

यह प्रश्न का पूर्ण उत्तर नहीं है, लेकिन मैं कुछ टिप्पणियों को जोड़ना चाहता था जिन्हें अन्य उत्तरों या टिप्पणियों में शामिल नहीं किया गया है।

  1. यह प्रश्न स्पष्ट रूप से माना जाता है कि हम एक सिमूला-शैली वस्तु उन्मुख भाषा के बारे में बात कर रहे हैं, जो स्वयं सीमित है। अधिकांश भाषाओं में, वस्तुओं के साथ भी, सब कुछ एक वस्तु नहीं है। विध्वंसक को लागू करने की मशीनरी एक ऐसी लागत लगाएगी जो हर भाषा कार्यान्वयनकर्ता भुगतान करने के लिए तैयार नहीं है।

  2. C ++ में विनाश के आदेश के बारे में कुछ निहित गारंटी है। यदि आपके पास एक पेड़ जैसी डेटा संरचना है, उदाहरण के लिए, माता-पिता से पहले बच्चे नष्ट हो जाएंगे। GC'd भाषाओं में ऐसा नहीं है, इसलिए पदानुक्रमित संसाधन अप्रत्याशित क्रम में जारी किए जा सकते हैं। गैर-स्मृति संसाधनों के लिए, यह बात कर सकता है।


2

जब दो सबसे लोकप्रिय जीसी फ्रेमवर्क (जावा और .NET) डिजाइन किए जा रहे थे, तो मुझे लगता है कि लेखकों को उम्मीद थी कि संसाधन प्रबंधन के अन्य रूपों की आवश्यकता से बचने के लिए अंतिम रूप से काम करना पर्याप्त होगा। 100% विश्वसनीय और निर्धारक संसाधन प्रबंधन को समायोजित करने के लिए आवश्यक सभी सुविधाओं की कोई आवश्यकता नहीं होने पर भाषा और रूपरेखा डिजाइन के कई पहलुओं को बहुत सरल बनाया जा सकता है। C ++ में, निम्नलिखित अवधारणाओं के बीच अंतर करना आवश्यक है:

  1. सूचक / संदर्भ जो एक वस्तु की पहचान करता है जो विशेष रूप से संदर्भ धारक के स्वामित्व में है, और जिसे किसी भी संकेतकर्ता / संदर्भ द्वारा नहीं पहचाना जाता है जिसके बारे में स्वामी को पता नहीं है।

  2. सूचक / संदर्भ जो एक श्रावक वस्तु की पहचान करता है जो विशेष रूप से किसी के पास नहीं है।

  3. सूचक / संदर्भ जो एक वस्तु की पहचान करता है, जो विशेष रूप से संदर्भ धारक के स्वामित्व में है, लेकिन जिस पर "दृश्य" के माध्यम से पहुँचा जा सकता है, मालिक के पास ट्रैकिंग का कोई तरीका नहीं है।

  4. सूचक / संदर्भ जो किसी वस्तु की पहचान करता है जो किसी वस्तु का दृश्य प्रदान करता है जो किसी और के स्वामित्व में है।

यदि GC भाषा / ढांचे को संसाधन प्रबंधन के बारे में चिंता करने की आवश्यकता नहीं है, तो उपरोक्त सभी को एक ही प्रकार के संदर्भ से बदला जा सकता है।

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


2

कचरा एकत्र करने वाली भाषाओं में वस्तु विध्वंसक प्रतिमान क्यों अनुपस्थित है?

मैं एक C ++ बैकग्राउंड से आता हूं, इसलिए यह क्षेत्र मेरे लिए चौंकाने वाला है।

सी ++ में विध्वंसक वास्तव में दो चीजों को संयुक्त करता है । यह रैम को मुक्त करता है और यह संसाधन आईडी को मुक्त करता है।

अन्य भाषाएं इन चिंताओं को अलग करती हैं जीसी मुक्त रैम के प्रभारी होने के साथ-साथ एक अन्य भाषा सुविधा मुक्त संसाधन आईडी का प्रभार लेती है।

मुझे यह बहुत कमी लगती है कि ये भाषाएं स्मृति को केवल प्रबंधन के लायक संसाधन मानती हैं।

यही जीसी सभी के बारे में हैं। वे केवल एक चीज का दान करते हैं और यह सुनिश्चित करना है कि आप स्मृति से बाहर न भागें। यदि RAM अनंत है, तो सभी GCs सेवानिवृत्त हो जाएंगे क्योंकि उनके अस्तित्व में आने का कोई वास्तविक कारण नहीं है।

सॉकेट्स, फ़ाइल हैंडल, एप्लिकेशन स्टेट्स के बारे में क्या?

भाषाएं संसाधन आईडी को मुक्त करने के विभिन्न तरीके प्रदान कर सकती हैं:

  • मैनुअल .CloseOrDispose()कोड भर में बिखरे हुए

  • मैनुअल .CloseOrDispose()" finallyब्लॉक" के भीतर बिखरे हुए

  • मैन्युअल "संसाधन आईडी ब्लॉक" (यानी using, with, try-साथ-संसाधन , आदि) जो automates .CloseOrDispose()ब्लॉक के बाद किया जाता है किया

  • गारंटीकृत "संसाधन आईडी ब्लॉक" जो.CloseOrDispose() ब्लॉक होने के बाद स्वचालित हो जाता है

कई भाषाएं मैनुअल (गारंटी के विपरीत) तंत्र का उपयोग करती हैं जो संसाधन कुप्रबंधन का अवसर बनाती है। यह सरल NodeJS कोड लें:

require('fs').openSync('file1.txt', 'w');
// forget to .closeSync the opened file

..जहां प्रोग्रामर खोली गई फ़ाइल को बंद करना भूल गया है।

जब तक कार्यक्रम चलता रहता है, तब तक खुली हुई फ़ाइल लिंबो में अटकी रहेगी। यह HxD का उपयोग करके फ़ाइल को खोलने की कोशिश करके सत्यापित करना आसान है और इसे सत्यापित नहीं किया जा सकता है:

यहाँ छवि विवरण दर्ज करें

C ++ विध्वंसक के भीतर मुक्त संसाधन आईडी भी गैर-गारंटीकृत है। आपको लगता है कि RAII गारंटीकृत "संसाधन आईडी ब्लॉक" की तरह काम करता है, फिर भी "संसाधन आईडी ब्लॉक" के विपरीत, C ++ भाषा RAII ब्लॉक को लीक होने से प्रदान करने वाली वस्तु को रोकती नहीं है , इसलिए RAII ब्लॉक कभी भी नहीं किया जा सकता है


ऐसा लगता है कि रूबी, जावास्क्रिप्ट / ES6 / ES7, Actionscript, Lua, आदि OOPy वस्तु समर्थन के साथ लगभग सभी आधुनिक कचरा एकत्र भाषाओं पूरी तरह से विध्वंसक / अंतिम प्रतिमान को छोड़ देते हैं। पायथन अपने वर्ग __del__()विधि के साथ एक ही लगता है । ऐसा क्यों है?

क्योंकि वे अन्य तरीकों का उपयोग करके संसाधन आईडी का प्रबंधन करते हैं, जैसा कि ऊपर बताया गया है।

भाषा डिजाइन निर्णय क्या हैं जो इन भाषाओं को ले जाते हैं और ऑब्जेक्ट निपटान पर कस्टम तर्क को निष्पादित करने का कोई तरीका नहीं है?

क्योंकि वे अन्य तरीकों का उपयोग करके संसाधन आईडी का प्रबंधन करते हैं, जैसा कि ऊपर बताया गया है।

एक भाषा में कस्टम इंस्टेंटेशन (निर्माणकर्ता) के साथ वर्ग या वर्ग जैसी संरचनाओं के साथ वस्तु उदाहरणों की अंतर्निहित अवधारणा क्यों होगी, फिर भी विनाश / अंतिम कार्यक्षमता को पूरी तरह से छोड़ देना चाहिए?

क्योंकि वे अन्य तरीकों का उपयोग करके संसाधन आईडी का प्रबंधन करते हैं, जैसा कि ऊपर बताया गया है।

मैं एक संभावित तर्क को देख सकता हूं कि भविष्य में कुछ अनिश्चित समय तक विध्वंसक / अंतिम रूप से कॉल नहीं किया जा सकता है, लेकिन यह जावा या पायथन को कार्यक्षमता का समर्थन करने से नहीं रोकता है।

जावा में विध्वंसक नहीं हैं।

जावा डॉक्स का उल्लेख :

अंतिम उद्देश्य का सामान्य उद्देश्य यह है कि वस्तु को पूरी तरह से त्यागने से पहले सफाई कार्य करना है। उदाहरण के लिए, एक इनपुट / आउटपुट कनेक्शन का प्रतिनिधित्व करने वाली किसी वस्तु के लिए अंतिम विधि स्पष्ट रूप से ऑब्जेक्ट को छोड़ने से पहले कनेक्शन को तोड़ने के लिए स्पष्ट I / O लेनदेन कर सकती है।

.. लेकिन संसाधन-आईडी प्रबंधन कोड Object.finalizerको मोटे तौर पर एक एंटी-पैटर्न ( cf. ) के रूप में माना जाता है । इसके बजाय कॉल साइट पर उन कोड को लिखा जाना चाहिए।

ऐसे लोग जो एंटी-पैटर्न का उपयोग करते हैं, उनका औचित्य यह है कि वे कॉल साइट पर रिसोर्स-आईडी जारी करना भूल गए होंगे । इस प्रकार, वे इसे अंतिम रूप में फिर से करते हैं, बस मामले में।

ऑब्जेक्ट फाइनल के किसी भी रूप का समर्थन नहीं करने के लिए मूल भाषा डिजाइन कारण क्या हैं?

फाइनल के लिए कई उपयोग के मामले नहीं हैं क्योंकि वे उस समय के बीच कोड का एक टुकड़ा चलाने के लिए होते हैं जब ऑब्जेक्ट के लिए कोई मजबूत संदर्भ नहीं होते हैं, और जिस समय यह मेमोरी जीसी द्वारा पुनर्प्राप्त की जाती है।

एक संभावित उपयोग मामला तब होता है जब आप GC के द्वारा ऑब्जेक्ट के बीच समय का एक लॉग रखना चाहते हैं और उस समय जब ऑब्जेक्ट के लिए कोई मजबूत संदर्भ नहीं होते हैं, जैसे:

finalize() {
    Log(TimeNow() + ". Obj " + toString() + " is going to be memory-collected soon!"); // "soon"
}

-1

डॉ। डॉब्स wrt c ++ में इस पर एक रेफरी पाया गया जिसमें अधिक सामान्य विचार हैं जो तर्क देते हैं कि विनाशकारी भाषा में समस्याग्रस्त हैं जहां उन्हें लागू किया जाता है। यहाँ एक मोटा विचार यह प्रतीत होता है कि विध्वंसकों का एक मुख्य उद्देश्य मेमोरी डीलोकेशन को संभालना है, और यह सही ढंग से पूरा करना मुश्किल है। मेमोरी को टुकड़े-टुकड़े में आवंटित किया जाता है, लेकिन विभिन्न ऑब्जेक्ट जुड़ जाते हैं और फिर डीलक्लोकेशन जिम्मेदारी / सीमाएं इतनी स्पष्ट नहीं होती हैं।

तो इस कचरे के संग्राहक का समाधान सालों पहले विकसित हुआ, लेकिन कचरा संग्रहण विधि के दायरे से गायब होने वाली वस्तुओं पर आधारित नहीं है (यह एक वैचारिक विचार है जिसे लागू करना कठिन है), लेकिन समय-समय पर चलने वाले कलेक्टर पर, कुछ हद तक neteterministically, जब ऐप "मेमोरी प्रेशर" का अनुभव करता है (यानी मेमोरी से बाहर चल रहा है)।

दूसरे शब्दों में "नव अप्रयुक्त वस्तु" की मानव अवधारणा वास्तव में कुछ मायनों में इस तरह से एक भ्रामक अमूर्तता है कि कोई भी वस्तु "तुरंत" अप्रयुक्त नहीं हो सकती है। अनुपयोगी वस्तुओं को केवल कचरा संग्रह एल्गोरिदम चलाकर "खोजा" जा सकता है जो ऑब्जेक्ट संदर्भ ग्राफ को पीछे छोड़ता है और सबसे अच्छा प्रदर्शन करने वाले एल्गोरिदम रुक-रुक कर चलता है।

यह संभव है कि एक बेहतर कचरा संग्रह एल्गोरिथ्म की खोज की जा सके, जो अप्रयुक्त वस्तुओं की तुरंत पहचान कर सके, जो तब लगातार विध्वंसक कॉलिंग कोड का कारण बन सकता है, लेकिन क्षेत्र में कई वर्षों के शोध के बाद एक भी नहीं मिला है।

फ़ाइलों या कनेक्शन जैसे संसाधन प्रबंधन क्षेत्रों का समाधान ऑब्जेक्ट "प्रबंधकों" को लगता है जो उनके उपयोग को संभालने का प्रयास करते हैं।


2
दिलचस्प खोज। धन्यवाद। लेखक का तर्क उस विध्वंसक पर आधारित है जो गलत समय पर कक्षा के उदाहरणों को उस मूल्य से पारित करने के कारण कहलाता है जहां कक्षा में एक उचित प्रतिलिपि निर्माता नहीं है (जो एक वास्तविक समस्या है)। हालांकि, यह परिदृश्य वास्तव में अधिकांश (यदि सभी नहीं) आधुनिक गतिशील भाषाओं में मौजूद नहीं है, क्योंकि सब कुछ संदर्भ द्वारा पारित किया जाता है जो लेखक की स्थिति से बचा जाता है। हालांकि यह एक दिलचस्प परिप्रेक्ष्य है, मुझे नहीं लगता कि यह बताता है कि क्यों सबसे अधिक कचरा एकत्र करने वाली भाषाओं ने विनाशकारी / अंतिम रूप देने की कार्यक्षमता को छोड़ दिया है।
dbcb

2
यह उत्तर डॉ। डॉब के लेख को गलत बताता है: लेख में यह तर्क नहीं दिया गया है कि विनाशकारी सामान्य रूप से समस्याग्रस्त हैं। लेख वास्तव में यह तर्क देता है: मेमोरी प्रबंधन प्राइमेटिव गोटो बयानों की तरह हैं, क्योंकि वे दोनों सरल लेकिन बहुत शक्तिशाली हैं। उसी तरह से जो गोटो के बयान "उचित रूप से सीमित नियंत्रण संरचनाओं" में सर्वोत्तम रूप से समझाया जाता है (देखें: डीजक्ट्सरा), मेमोरी प्रबंधन प्राइमेटिव "उचित रूप से सीमित डेटा संरचनाओं में सर्वोत्तम रूप से समझाया गया है।" विध्वंसक इस दिशा में एक कदम है, लेकिन बहुत दूर नहीं है। अपने लिए तय करें कि यह सच है या नहीं।
kdbanman
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.