2010-02-26 10 views
18

जीसी प्रबंधित वस्तुओं के लिए है और अंतिम रूप से अप्रबंधित वस्तुओं के लिए है जो मैं पढ़ रहा हूं। निपटान निहित है और अंतिम रूप से स्पष्ट है जो मैं पढ़ रहा हूं। क्या कोई मुझे एक मॉड्यूल का एक उदाहरण दे सकता है जिसमें विभिन्न तीन कारणों से सभी तीन चीजें उपयोग की गई हैं?जीसी, अंतिमकरण() और निपटान के बीच संबंध क्या है?

+4

आप उस मिश्रण में 'उपयोग' भी जोड़ सकते हैं जब आप इसमें हों। – RedFilter

उत्तर

25

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

निपटान और अंतिमकरण विधियां संसाधनों की सफाई के लिए एक विकल्प प्रदान करती हैं, जो जीसी द्वारा संचालित नहीं हैं। जैसे यह देशी हैंडल और पसंद हो सकता है। उनके पास प्रबंधित ढेर पर स्मृति को पुनः प्राप्त करने के साथ कुछ लेना देना नहीं है।

निपटान को IDisposable लागू करने वाले प्रकार पर स्पष्ट रूप से बुलाया जाना चाहिए। इसे या तो Dispose() विधि के माध्यम से या using निर्माण के माध्यम से कहा जा सकता है। जीसी स्वचालित रूप से निपटान नहीं करेगा।

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

Dispose() संसाधनों के निर्धारक सफाई की अनुमति देता है जबकि अंतिम उपयोगकर्ता सुरक्षा कोड के रूप में कार्य कर सकता है यदि उपयोगकर्ता Dispose() पर कॉल नहीं करता है।

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

यदि आप इसमें खोदना चाहते हैं, तो मैं CLR via C# by Jeffrey Richter की अनुशंसा करता हूं। यह एक महान किताब है और इसमें इसके सभी विवरणों को शामिल किया गया है (मैंने कई विवरण छोड़े हैं)। नया तीसरा संस्करण अभी जारी किया गया था।

+1

+1, लेकिन आप यह जोड़ सकते हैं कि आप जीसी.SupressFinalize के साथ फाइनलाइज़र को दबा सकते हैं, जो कुछ ऐसा करना है जिसे आप स्पष्ट रूप से उदाहरण का निपटान करते हैं। –

+0

यदि किसी ऑब्जेक्ट को क्लीनअप के लिए योग्य होने पर अंतिम रूप से कॉल किया जाता है तो सी ऐसा क्यों नहीं करता है? अगर यह एक स्वचालित प्रक्रिया है? – TeaLeave

+0

इसे तुरंत नहीं कहा जाता है। इसे बुलाया जाना निर्धारित है। इसे चलाने से पहले कुछ समय लग सकता है। –

7

आप केवल IDisposable, फ़ाइनलाइजर्स और कचरा संग्रह, शॉन फर्कस 'CLR Inside Out: Digging into IDisposable पर निश्चित लेख को पढ़ना चाहते हैं।

यह आलेख इस विषय के बारे में बहुत कम संदेह छोड़ देता है।

+2

हाय मार्क, डिप्लोस() और अन्य दो के बीच का अंतर मुझे समझ में आया है, लेकिन जहां मैं संघर्ष कर रहा हूं वह अंतिम() और कचरा कलेक्टर() के बीच अंतर को समझना है। क्योंकि वहां कई लेख हैं जहां मैं लेखक कहता हूं कि जीसी अंततः वस्तुओं को मिटा देने के लिए अंतिम() का उपयोग करता है। फिर कक्षा परिभाषा में अंतिम() को रखने और एक को रखने के बीच अंतर क्या है क्योंकि भले ही मैं अपनी कक्षा परिभाषा में अंतिम() को अंतिम रूप से नहीं रखता, जीसी अंततः अप्रयुक्त वस्तु को मिटा देने के लिए अंतिम रूप() को कॉल कर रहा है। – TeaLeave

+0

अब, कहीं मैंने पढ़ा है कि अंतिमकरण() के साथ ऑब्जेक्ट्स को "अंतिमकरण कतार" में रखा जाएगा और फिर जब ऑब्जेक्ट की आवश्यकता नहीं है तो स्मृति को जीसी पुनः प्राप्त किया जाएगा। – TeaLeave

+0

चीजें इतनी उलझन में लगती हैं क्योंकि जीसी usign को अंतिम रूप दिया जाता है() और अंतिम रूप जीसी का उपयोग कर रहा है :)। मैं उलझन में हूं ......... – TeaLeave

8

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

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

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

अधिकांश नमूने के साथ समस्या यह है कि IDISposable का उपयोग करने के कई कारण हैं, और उचित कार्यान्वयन इस कारण के आधार पर भिन्न होता है कि आप इसका उपयोग कर रहे हैं। उदाहरण के लिए, यदि आप सीधे मूल संसाधन को लपेटते हैं, तो आपको एक अंतिमकर्ता को कार्यान्वित करना चाहिए, लेकिन यदि आप एक और आईडीस्पोज़ेबल प्रकार को समाहित करते हैं, तो अंतिमकरण आवश्यक नहीं है, भले ही आपको अभी भी IDISposable लागू करना चाहिए। इसे संबोधित करने के लिए, मैंने IDisposable and finalization in depth on my blog लिखा है, जिसमें कई कारणों से आप IDisposable, और विभिन्न पैटर्न के लिए विभिन्न कारणों का वर्णन करेंगे।

संबंधित मुद्दे