2010-06-30 21 views
7

मैं जानना चाहता हूं कि जब हम निपटान() विधि को कॉल करते हैं तो कौन सी कार्रवाई की जाती है। ऑब्जेक्ट ऑब्जेक्ट को कचरा संग्रह के लिए तैयार है() कॉल या डिस्प्ले() अंक पर सभी संसाधनों को जल्दी से मुक्त करता है। और क्या हुआ जब हमने ऑब्जेक्ट संदर्भ को पूर्ण किया। दरअसल मेरे पास .NET 2.0 में विंडोज़ फॉर्म एप्लीकेशन है। और मैं सभी अपरिवर्तित ऑब्जेक्ट एकत्र करने के लिए कुछ समय बीतने के बाद कचरा कलेक्टर को कॉल करना चाहता हूं (5 मिनट के बाद उदाहरण के लिए)।कचरा संग्रह का उपयोग?

उत्तर

7

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

निपटान विधि में ऑब्जेक्ट को सभी अप्रबंधित संसाधनों, जैसे डेटाबेस कनेक्शन और फ़ॉन्ट ऑब्जेक्ट्स का ख्याल रखना चाहिए।

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

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

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

+2

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

+0

@tvanfosson: इसके बारे में अभी भी कुछ भी जादू नहीं है, और यह 'उपयोग' कथन है जो विशेष रूप से निपटान विधि पर लक्षित कुछ करता है, निपटान विधि अभी भी एक साधारण विधि है। – Guffa

+0

मुझे एहसास है कि विधि अन्य विधियों से किसी भी भौतिक सम्मान में भिन्न नहीं है, लेकिन मैं कहूंगा कि यह कुछ हद तक जादुई है कि उपयोग ब्लॉक से बाहर निकलने पर इसे स्वचालित रूप से लागू किया जाता है। – tvanfosson

-1

ऑब्जेक्ट केवल कचरा संग्रह के लिए चिह्नित है, जब निपटान() कहा जाता है। < - अद्यतन: यह गलत है। निपटान() वास्तव में कुछ भी नहीं करता है, जब तक कि यह आपके द्वारा या संकलक द्वारा नहीं कहा जाता है (जब 'उपयोग' निर्माण में उपयोग किया जाता है)।

MSDN से -

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

मजबूर करने के लिए यह लेख देखें द्वारा कचरा संग्रहण पैदा कर सकते हैं - http://msdn.microsoft.com/en-us/library/bb384155.aspx

+0

आपके उत्तर के बारे में निश्चित नहीं है ... –

+2

यह सही नहीं है। निपटान का निर्धारण निर्धारिती अंतिम रूप के रूप में किया जाता है, लेकिन ऑब्जेक्ट्स जो एक्सपोज़ेबल का पर्दाफाश नहीं करते हैं, अभी भी जीसी द्वारा एकत्र किए जाएंगे। – captaintom

+1

"-1" आपने जीसी.कोलेक्ट() विवरण को प्रतिबिंब दिया। ऐसा कुछ भी नहीं है जैसे "वस्तु केवल कचरा संग्रह के लिए चिह्नित होती है, जब निपटान() को" – Arseny

-1

आप वास्तव में एक कूड़ा संग्रह उपयोग कराने के लिए करना चाहते हैं:

GC.Collect(); 

कृपया कारणों के लिए इस पोस्ट को देख क्यों आप इसका इस्तेमाल नहीं करना चाहिए:

What's so wrong about using GC.Collect()?

+0

लेकिन * क्या आपको कचरा संग्रह को मजबूर करना चाहिए? लगभग सभी मामलों में: नहीं! – dtb

+2

-1 आप यह बताने के लिए भूल गए हैं कि जिस कोड को आपने अभी उसे दिया है उसका उपयोग नहीं किया जाना चाहिए, और क्यों। – Guffa

+0

लेकिन इसका उपयोग तब तक न करें जब तक आप वास्तव में सुनिश्चित न हों कि यह सहायता करने जा रहा है। दस्तावेज़ कहते हैं, उदाहरण के लिए: "अपने आवेदन के कोड में निर्धारित बिंदु पर उपयोग की जाने वाली स्मृति की मात्रा में महत्वपूर्ण कमी होने पर संग्रह विधि का उपयोग करें।" मैंने इसे ऐसे प्रोग्राम में उपयोग किया है जो नौकरियों के बीच या दाएं को साफ करने के लिए काम की एक बड़ी मात्रा में काम करता है, जो प्रोग्राम कुछ भी नहीं कर रहा था जब स्मृति पदचिह्न को कम करने में मदद करता था। –

9

Dispose सामान्यतः frees unmanaged resources owned by the object। कॉलिंग Dispose कचरा संग्रह ट्रिगर नहीं करता है; आपकी ऑब्जेक्ट तब एकत्र की जाती है जब इसके बारे में कोई संदर्भ नहीं होता है, वैसे ही जैसे आप कभी Dispose नहीं कहेंगे।

null पर किसी ऑब्जेक्ट संदर्भ को सेट करना केवल उस ऑब्जेक्ट को इंगित करने के संदर्भ का कारण बनता है; आपको आमतौर पर ऐसा करने की आवश्यकता नहीं है (उदाहरण के लिए, आपको स्थानीय चर को null पर सेट करने की आवश्यकता नहीं है)।

आपको लगभग कचरा संग्रह स्वयं को ट्रिगर करने की आवश्यकता नहीं है, या तो। क्या आप एक समस्या देख रहे हैं जो बताती है कि रनटाइम चुनने पर उस बिंदु के बजाय आपको हर 5 मिनट में कचरा संग्रहण चलाने की ज़रूरत है?

+0

ठीक है।आप सभी को धन्यवाद। मैं निपटान() और कचरा कलेक्टर के बारे में बहुत कुछ समझता हूं। –

0

स्वचालित कचरा संग्रह का बिंदु यह है कि आपको वस्तुओं को मुक्त करने के बारे में चिंता करने की आवश्यकता नहीं है। कचरा कलेक्टर "मदद" करने की कोशिश मत करो।

ऑब्जेक्ट्स स्कोप से बाहर निकलने के बाद अंततः कचरा एकत्रित होते हैं। ऑब्जेक्ट को "मुक्त" करने का कोई तरीका नहीं है या इसे तेजी से कचरा संग्रह के लिए चिह्नित करें। बस ध्यान रखें कि कौन सी वस्तुएं गुंजाइश में हैं (या दायरे में वस्तुओं से संदर्भित)।

निपटान विधि सिर्फ एक विधि है। यह कचरा संग्रह से संबंधित कुछ भी नहीं करता है।

using (var x = expr) { ... } 

है जब इसके खिलाफ आयोजित नहीं संदर्भ होते हैं मूल रूप से

var x = expr; 
try { ... } finally { x.Dispose(); } 
2

एक वस्तु जीसी के लिए elligible है के बराबर: "फेंक" विधि कि using बयान से जानी जाती है नाम एक ही है यह। यदि इसके पास एक निश्चित समय अवधि (कचरा कलेक्टर द्वारा प्रबंधित) के लिए इसके खिलाफ संदर्भ हैं, तो इसे "पीढ़ी" के रूप में जाना जाता है।

निपटान विधि बस एक पैटर्न (नहीं एक भाषा लगाया वस्तु विलोपन तंत्र) कहना है कि वस्तु अब किसी भी अप्रबंधित संसाधनों साफ कर सकते हैं, है बंद बंद निपटान द्वारा किया जाता है किसी भी कनेक्शन आदि

कार्रवाई विधि पूरी तरह से प्रोग्रामर द्वारा नियंत्रित होती है, क्योंकि आप जानते हैं कि यह कुछ भी नहीं कर सकता है।

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

ध्यान दें कि यदि कोई निपटान नहीं किया जाता है तो किसी भी प्रबंधित संसाधन अंततः जीसीएड (जब तक संदर्भ आयोजित नहीं होते)। हालांकि, अप्रबंधित संसाधन केवल तभी पुनः प्राप्त किए जाएंगे जब आपकी संपूर्ण एप्लिकेशन प्रक्रिया समाप्त हो जाएगी (साथ ही साथ संदर्भित किसी भी प्रबंधित संसाधन के साथ)।

+1

एक तरफ, 'निपटान' कार्यान्वयन में अक्सर 'जीसी। सप्रप्रेसफिनलाइज (यह)' पर कॉल शामिल होता है, ताकि ऑब्जेक्ट कचरा इकट्ठा होने पर अंतिम बार दूसरी बार न हो। – Brian

0

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

null सेटिंग के संबंध में हम कह सकते हैं कि यह बेकार है।यह सिर्फ नोटों वस्तु के लिए कोई संदर्भ है कि वहाँ इस तरह यह GC के लिए उम्मीदवार हो जाता है, लेकिन फिर से nullGC के रूप में स्थापित करने के पा सकते हैं वहाँ कि बिना वस्तु का कोई सन्दर्भ हैं कि के लिए कोई जरूरत नहीं है कि ..

बुला लिए Collect यह सुझाव नहीं दिया जाता है (जब तक आपके पास अत्यधिक आवश्यकता और तर्क नहीं है) क्योंकि जीसी ने यह जानकर अनुकूलित किया कि Collection के लिए सही समय क्या है।

+0

"लेकिन आमतौर पर निपटान ऑब्जेक्ट को जीसी के लिए उम्मीदवार बनाता है।" ... उम, नहीं। – captaintom

+0

निपटान किसी ऑब्जेक्ट को उम्मीदवार नहीं बनाता है - आप वस्तु को संदर्भित करने से रोकने के लिए संदर्भ का संदर्भ रख सकते हैं। यदि डेवलपर सही ढंग से अपना काम कर रहा है, तो निपटान किसी ऑब्जेक्ट-आंतरिक संसाधनों को साफ करना चाहिए। –

+0

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

0

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

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

implement the IDisposable pattern पर चर्चा के लिए एमएसडीएन देखें।

1

अन्य लोगों ने यहां जवाब दिया है कि "IDisposable कचरा कलेक्टर के साथ कैसे बातचीत करता है" और "मुझे GC.Collect कहां से कॉल करना चाहिए" प्रश्न के कुछ हिस्सों।

मेरे पास एक ब्लॉग पोस्ट है जो when you should set variables to null to help the garbage collector (प्रश्न का तीसरा हिस्सा) के बारे में विस्तार से बताता है। संक्षिप्त जवाब "लगभग कभी नहीं, जब तक कि यह एक स्थिर चर नहीं है।"

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