2010-08-08 10 views
115

मैं अप्रबंधित संसाधनों के बारे में जानना चाहता हूं। क्या कोई मुझे एक बुनियादी विचार दे सकता है?अप्रबंधित संसाधन वास्तव में क्या हैं?

+0

यह पृष्ठ भी देखें, जो IDISposable के उचित उपयोग के लिए एक शानदार स्पष्टीकरण और पैटर्न प्रदान करता है, और अप्रबंधित संसाधनों को खाते में कैसे लेना है: http://stackoverflow.com/questions/538060/proper-use-of-the -idisposable-interface –

उत्तर

133

प्रबंधित संसाधनों का मूल रूप से "प्रबंधित स्मृति" का अर्थ है जो कचरा कलेक्टर द्वारा प्रबंधित किया जाता है। जब आपके पास किसी प्रबंधित ऑब्जेक्ट (जो प्रबंधित स्मृति का उपयोग करता है) के लिए कोई संदर्भ नहीं है, तो कचरा कलेक्टर (अंत में) आपके लिए उस स्मृति को रिलीज़ करेगा।

अप्रबंधित संसाधन तब सब कुछ हैं जो कचरा कलेक्टर के बारे में नहीं जानता है। उदाहरण के लिए:

  • फ़ाइलें खोलें
  • ओपन नेटवर्क कनेक्शन
  • अप्रबंधित स्मृति
  • XNA में: शिखर बफ़र्स, सूचकांक बफ़र्स, बनावट, आदि

आम तौर पर आप उन रिलीज़ करना चाहते अप्रबंधित संसाधन से पहले आप उन्हें प्रबंधित करने वाले ऑब्जेक्ट के सभी संदर्भ खो देते हैं। using कथन का उपयोग करके Dispose का उपयोग करके आप उस ऑब्जेक्ट पर Dispose पर कॉल करके या (सी # में) कॉल करके ऐसा करते हैं।

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

यदि आप स्वयं को एक वर्ग को लागू करते हैं जो अप्रबंधित संसाधनों को संभालता है, तो यह आपके ऊपर Dispose और Finalize लागू करने के लिए है।

+3

ओपन डाटाबेस कनेक्शन किस श्रेणी के अंतर्गत आता है? प्रबंधित/अप्रबंधित? –

+6

+1 अन्य उत्तरों उस महत्वपूर्ण बिंदु को याद करते हैं जिसे आप कॉल कर रहे हैं * * प्रबंधित * ऑब्जेक्ट पर निपटान करें जो आंतरिक रूप से अप्रबंधित संसाधन को मुक्त करने के लिए संभालता है (जैसे फाइल हैंडल, जीडीआई + बिटमैप, ...) और यदि आप अप्रबंधित पहुंचते हैं संसाधन सीधे (PInvoke आदि) आपको इसे संभालने की जरूरत है। –

+2

@ डेव: अप्रबंधित - क्योंकि जीसी इसके बारे में नहीं जानता (मान लीजिए कि आप कुछ काल्पनिक इन-प्रबंधित-मेमोरी डेटाबेस का उपयोग नहीं कर रहे हैं)। लेकिन कनेक्शन ऑब्जेक्ट * स्वयं * एक अप्रबंधित संसाधन नहीं रख सकता है। संभवतः डेटाबेस कनेक्शन एक खुली फ़ाइल या नेटवर्क कनेक्शन * कहीं * का उपयोग करता है - लेकिन यह * संभव * है कि एक अन्य ऑब्जेक्ट (कनेक्शन ऑब्जेक्ट के अलावा) उस अप्रबंधित संसाधन को संभालने में सक्षम है (शायद आपके डेटाबेस लाइब्रेरी कैश कनेक्शन)। दस्तावेज़ीकरण की जांच करें और देखें कि यह कहां से 'निपटान' कहने के लिए कहता है या 'उपयोग' का उपयोग करें। –

4

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

here से चोरी, पूरी पोस्ट को पढ़ने के लिए स्वतंत्र महसूस करें।

9

अप्रबंधित संसाधन हैं जो .NET रनटाइम (सीएलआर) (उर्फ गैर- .NET कोड) के बाहर चलते हैं। उदाहरण के लिए, Win32 API में एक DLL को कॉल करें, या C++ में लिखे गए .dll पर कॉल करें ।

3

एक "अप्रबंधित संसाधन" एक बात नहीं है, बल्कि एक ज़िम्मेदारी है। यदि किसी ऑब्जेक्ट का एक अप्रबंधित संसाधन है, जिसका अर्थ है कि (1) इसके बाहर कुछ इकाई को इस तरह से छेड़छाड़ की गई है जो साफ़ नहीं होने पर समस्याएं पैदा कर सकती है, और (2) ऑब्जेक्ट में ऐसी सफाई करने के लिए आवश्यक जानकारी है और यह ज़िम्मेदार है ऐसा करने के लिए

हालांकि कई प्रकार के अप्रबंधित संसाधन विभिन्न प्रकार के ऑपरेटिंग सिस्टम इकाइयों (फाइलें, जीडीआई हैंडल, आवंटित मेमोरी ब्लॉक इत्यादि) से बहुत दृढ़ता से जुड़े हुए हैं, लेकिन उनमें से कोई भी प्रकार की इकाई नहीं है जिसे अन्य सभी द्वारा साझा किया जाता है सफाई की ज़िम्मेदारी से।आम तौर पर, यदि किसी ऑब्जेक्ट को क्लीनअप करने की ज़िम्मेदारी है, तो इसमें एक डिस्पोजेक्ट विधि होगी जो इसे सभी क्लीनअप करने के लिए निर्देशित करती है जिसके लिए यह ज़िम्मेदार है।

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

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

1

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

31

कुछ उपयोगकर्ता प्रबंधित संसाधनों के बीच खुली फ़ाइलें, डीबी कनेक्शन, आवंटित स्मृति, बिटमैप्स, फ़ाइल स्ट्रीम आदि रैंक करते हैं, अन्य अप्रबंधित लोगों के बीच। तो क्या वे प्रबंधित या अप्रबंधित हैं?

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

डीबी के साथ समान: यदि आप कुछ डीबी असेंबली का उपयोग करते हैं, तो आपके पास डीबीकनेक्शन आदि जैसे वर्ग हैं, वे .NET और प्रबंधित हैं। लेकिन वे "गंदे काम" को लपेटते हैं, जो अप्रबंधित है (सर्वर पर स्मृति आवंटित करें, इसके साथ कनेक्शन स्थापित करें ...)। यदि आप इस रैपर वर्ग का उपयोग नहीं करते हैं और कुछ नेटवर्क सॉकेट खोलते हैं और कुछ कमांड का उपयोग करके अपने अजीब डेटाबेस से संवाद करते हैं, तो यह अप्रबंधित है।

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

यदि आप अपनी कक्षा में अंतर्निहित .NET या तृतीय पक्ष रैपर कक्षाओं और कुछ असेंबलर निर्देशों द्वारा खुली फ़ाइलों का उपयोग नहीं करते हैं, तो ये खुली फ़ाइलें अप्रबंधित हैं और आपको पैटर्न का निपटान/अंतिम रूप लागू करना होगा। यदि आप नहीं करते हैं, तो स्मृति रिसाव, हमेशा लॉक संसाधन आदि होगा, भले ही आप इसका उपयोग नहीं करते हैं (फ़ाइल ऑपरेशन पूर्ण) या एप्लिकेशन समाप्त होने के बाद भी।

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

+0

आपके उत्तर के लिए 'अप्रबंधित बनाम प्रबंधित संसाधनों' –

+0

thx पर अतिरिक्त स्पष्टता पर अच्छा है। कौन सी कक्षाओं की सिफारिश की जाती है कि हम वास्तव में निपटान पर कॉल करें? – BKSpurgeon

+0

यह आसान है। आपके द्वारा उपयोग की जाने वाली प्रत्येक कक्षा पर, आपको सत्यापित करना होगा कि क्या यह IDISposable इंटरफ़ेस लागू करता है। यदि हां, तो यदि आप इस तरह के वर्ग को एक विधि में उपयोग करते हैं (उदाहरण: फ़ाइल खोलना, टेक्स्ट संग्रह करना, फ़ाइल बंद करना), तो आप इसका उपयोग() {} पैटर्न का उपयोग कर सकते हैं, जो आपके लिए स्वचालित रूप से निपटान करता है। यदि आप इस तरह के वर्ग को अधिक तरीकों से उपयोग करते हैं (उदाहरण: आपकी कक्षा में फ़ाइल है, तो कन्स्ट्रक्टर में यह फ़ाइल खोलता है, फिर कई विधियां कुछ लॉग जोड़ती हैं ...), तो आपको अपनी कक्षा द्वारा आईडीस्पोजेबल इंटरफ़ेस को कार्यान्वित करना होगा, निपटान/अंतिम रूप पैटर्न को कार्यान्वित करना होगा और उस वर्ग की वस्तु का सही ढंग से निपटान करें। – Martas

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