2009-01-29 11 views
24

मैं MSDN article about how to implement IDisposable पढ़ रहा था और मैं लेख में उद्धृत प्रबंधित और मूल संसाधनों के बीच अंतर के बारे में अनिश्चित हूं।निपटान करते समय प्रबंधित और देशी संसाधनों के बीच क्या अंतर है? (.NET)

मेरे पास एक कक्षा है जिसे निपटाने के दौरान अपने 2 क्षेत्रों को निपटाना होगा। क्या मुझे उन्हें प्रबंधित के रूप में व्यवहार करना चाहिए (केवल तभी निपटाना जब सही = निपटान करना) या मूल संसाधन?

उत्तर

18

एक प्रबंधित संसाधन एक और प्रबंधित प्रकार है, जो IDisposable लागू करता है। आपको उपयोग किए जाने वाले किसी अन्य IDisposable प्रकार पर Dispose() पर कॉल करने की आवश्यकता है। मूल निवासी संसाधन जैसे देशी विंडोज के रूप में कामयाब रहे दुनिया के बाहर कुछ भी हैंडल आदि हैं


संपादित: टिप्पणी में सवाल का जवाब (टिप्पणी के लिए बहुत लंबा)

नहीं है कि सिर्फ एक कामयाब प्रकार है। एक सही ढंग से निर्मित प्रकार, जो IDisposable को लागू नहीं करता है कचरा कलेक्टर द्वारा संभाला जाएगा और आपको कुछ और करने की ज़रूरत नहीं है। यदि आपका प्रकार सीधे मूल संसाधन का उपयोग करता है (उदा। Win32 पुस्तकालयों को कॉल करके), आपको IDisposable को अपने प्रकार पर लागू करना होगा और Dispose विधि में संसाधनों का निपटान करना होगा। यदि आपका प्रकार किसी अन्य प्रकार से encapsulated एक मूल संसाधन का उपयोग करता है जो IDisposable लागू करता है, तो आपको Dispose इस प्रकार के उदाहरणों पर Dispose() पर कॉल करना होगा।

+0

तो एक प्रबंधित प्रकार है कि IDisposable एक अप्रबंधित संसाधन को लागू नहीं करता है के साथ अपने प्रबंधित सफाई की रखवाली? हो सकता है कि मैं प्रकार छंद संसाधन द्वारा भ्रमित हो रहा हूं ... –

+0

@Yooder: आपके पास एक प्रबंधित संसाधन कैसे हो सकता है जिसे किसी प्रकार से प्रदर्शित नहीं किया जाता है? –

+0

@ लैरीफिक्स: अलग-अलग लोग शब्दावली का अलग-अलग उपयोग करते हैं, लेकिन मैं कहूंगा कि एक ऑब्जेक्ट जिसने कुछ और * कुछ और करने के लिए नहीं कहा है, आगे की सूचना तक, और दूसरों के नुकसान के लिए, कोई भी नहीं है * संसाधन। – supercat

21

ब्रायन की जवाब देने के लिए एक छोटे से जोड़ सकते हैं और अपनी टिप्पणी/सवाल करने के लिए:

एक प्रबंधित/अप्रबंधित संसाधन के बीच अंतर यह है कि कचरा कलेक्टर कामयाब संसाधनों के बारे में पता है और अप्रबंधित संसाधनों के बारे में पता नहीं है। मुझे पता है कि जवाब बहुत ठोस नहीं है लेकिन अंतर बहुत बड़ा है।

मदद करने के लिए रेत यहाँ में रेखा खींचना कैसे जीसी रन की कमी (और शायद थोड़ा त्रुटियों से छलनी) संस्करण है और स्मृति को साफ:

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

.NET फ्रेमवर्क ऑब्जेक्ट्स के साथ काम करने वाले लगभग सभी मामलों में आपको आश्वासन दिया जा सकता है कि ऑब्जेक्ट प्रबंधित किए जाते हैं (.NET लगभग सभी अप्रबंधित संसाधनों के प्रबंधित रैपर प्रदान करता है ताकि यह सुनिश्चित किया जा सके कि वे ठीक से साफ हो गए हैं); अन्य तृतीय पक्ष घटक जो Win32 API (या आपके घटकों को ऐसा करते हैं) में हुक करते हैं वे ऑब्जेक्ट्स हैं जो चिंता का कारण हो सकते हैं।

कुछ .NET ऑब्जेक्ट्स हैं जिन्हें कुछ हद तक अप्रबंधित माना जा सकता है। ग्राफिक्स पुस्तकालय के घटक एक उदाहरण हैं।

अधिकांश ".NET मेमोरी लीक" वास्तव में वास्तविक अर्थ में स्मृति रिसाव नहीं हैं। आम तौर पर वे तब होते हैं जब आप सोचते हैं आपने किसी ऑब्जेक्ट को उपयोग से हटा दिया है लेकिन वास्तव में ऑब्जेक्ट में अभी भी एप्लिकेशन का कुछ संदर्भ है। एक आम उदाहरण Eventhandlers जोड़ रहा है (obj.SomeEvent + = OnSomeEvent -or- AddHandler obj.SomeEvent, पताOf OnSomeEvent) और उन्हें हटा नहीं रहा है।

ये 'लिंग संदर्भ' तकनीकी रूप से मेमोरी लीक नहीं हैं क्योंकि आपका एप्लिकेशन अभी भी तकनीकी रूप से उनका उपयोग कर रहा है; हालांकि यदि उनमें से पर्याप्त हैं तो आपके आवेदन को गंभीर प्रदर्शन प्रभाव भुगत सकते हैं और संसाधन समस्याओं के संकेत दिखा सकते हैं (आउटऑफमेमरी अपवाद, खिड़की हैंडल प्राप्त करने में असमर्थ आदि)।

मैं एक मध्यवर्ती .NET डेवलपर हूं और दुर्भाग्य से इन समस्याओं के बारे में पहले से पता हूं। मैं लिंटिंग संदर्भों से परिचित होने में मदद करने के लिए एएनटीएस प्रोफाइलर के साथ खेलने की सलाह देता हूं (एक नि: शुल्क परीक्षण संस्करण है) या यदि आप प्रबंधित ढेर को देखने के लिए WinDbg और SOS.DLL का उपयोग करके थोड़ा और अधिक नट-किरकिरा शोध प्राप्त करना चाहते हैं। यदि आप बाद में देखने का फैसला करते हैं तो मैं टेस फेरांडेज़ ब्लॉग पढ़ने की सलाह देता हूं; विंडबग प्रभावी ढंग से

+3

मुझे आपका जवाब पसंद है।प्रबंधित और अप्रबंधित संसाधनों के बीच सबसे महत्वपूर्ण भेद यह नहीं है कि वे जीसी दुनिया के भीतर मौजूद हैं, लेकिन क्या जीसी को पता चलेगा कि अगर उन्हें त्याग दिया जाता है तो सभी आवश्यक सफाई कैसे करें। यदि कुछ साफ करने में विफल होने से सिस्टम कार्यक्षमता खराब हो सकती है, लेकिन एक स्तर -2 जीसी इसका ख्याल रखेगा, यह एक प्रबंधित संसाधन है। अगर कुछ साफ करने में विफल होने से सिस्टम की कार्यक्षमता खराब हो सकती है, और यहां तक ​​कि दोहराए गए स्तर -2 जीसी की मदद नहीं होगी, यह एक अप्रबंधित संसाधन है। – supercat

1

संक्षिप्त जवाब कुछ भी होगा जो आप सीएलआर की पीठ (ओएस में) के पीछे जाने के लिए कुछ भी होगा, जिसे 'देशी' कहा जा सकता है।

  • अप्रबंधित स्मृति आवंटन। यदि आप एक प्रबंधित वर्ग CantstayManaged में स्मृति का एक हिस्सा बनाते हैं, तो CantStayManaged इस स्मृति (संसाधन) को मुक्त करने के लिए ज़िम्मेदार है।
  • फ़ाइलें, पाइप, घटनाओं, तुल्यकालन निर्माणों, आदि के लिए हैंडल - एक अंगूठे का नियम के रूप में यदि आप संकेत दिए गए/एक संसाधन के लिए हैंडल प्राप्त करने के लिए WinAPIs फोन, तो उन हैं 'देशी संसाधनों'

तो अब CantStayManaged एडीयू बोलने से पहले इसे 2 चीजों को साफ करने की ज़रूरत है।

  1. प्रबंधित: सदस्य फ़ील्ड और सीएलआर आवंटित कोई भी संसाधन। यह आमतौर पर आपके 'डिस्पोजेबल' सदस्य ऑब्जेक्ट्स पर निपटान को कॉल करने के बराबर होता है।
  2. अप्रबंधित: सभी स्नीकी कम-स्तरीय सामान जो हम अपनी पीठ के पीछे खींचते हैं।

ऑब्जेक्ट क्लीनअप को अभी ट्रिगर किया जा सकता है 2 तरीके हैं।

  1. निपटान (सही) मामले: आप स्पष्ट रूप से अपने निपटान प्रकार पर कहा जाता है। अच्छा प्रोग्रामर
  2. निपटान (झूठा) मामला: आप निपटान को कॉल करना भूल गए हैं, जिस स्थिति में फाइनलर को लात मारना चाहिए और अभी भी उचित सफाई सुनिश्चित करना चाहिए।

दोनों मामलों में, अप्रबंधित संसाधनों को 'लेक!', 'क्रैश!' से मुक्त किया जाना चाहिए। et.all सतह। लेकिन आपको केवल निपटान() पूर्व मामले में केवल प्रबंधित संसाधनों को साफ़ करने का प्रयास करना चाहिए। बाद वाले/अंतिम मामले में - सीएलआर पहले से ही आपके कुछ सदस्यों को अंतिम रूप दे सकता है और एकत्र कर सकता है, इसलिए आपको उन तक नहीं पहुंचना चाहिए (सीएलआर ऑर्डर ग्राफ़ को अंतिम रूप देने के क्रम में गारंटी नहीं देता है।) इसलिए आप इससे जुड़े मुद्दों से बचते हैं एक if (AmIBeingCalledFromDispose) गार्ड जांच

HTH

+0

जबकि मूल संसाधन जो सीधे आयोजित किए जाते हैं, अप्रबंधित संसाधन होते हैं, लेकिन प्रबंधित कोड के भीतर पूरी तरह से अप्रबंधित संसाधन होना संभव है। एक वस्तु जो "संसाधन" रखती है वह वह है जिसने दूसरों की संभावित हानि के लिए आगे की सूचना तक, इसके पक्ष में कुछ करने के लिए कुछ और करने के लिए कहा है। एक संसाधन जिसे छोड़कर जीसी द्वारा ठीक से साफ नहीं किया जाएगा, एक अप्रबंधित संसाधन है। – supercat

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