2010-01-07 14 views
6

कचरा कलेक्टर के लिए क्या गारंटी है? कचरा संग्रहण गारंटी

  • जब यह: यदि कोई संदर्भ है

    • अगर अभी स्मृति यह कचरा एकत्र नहीं किया जाएगा
    • लिए एक संदर्भ है:

      अपना शोध से मुझे लगता है में कामयाब रहे जीसी गैर निर्धारक

    • है जब अंतिम रिलीज में जीसी किक्स स्मृति जारी होने से पहले चलाया जाएगा।
    • फाइनलाइजर्स के आदेश के बारे में कोई गारंटी नहीं है (इसलिए मान लीजिए कि माता-पिता बच्चे के सामने भाग लेंगे)।

लेकिन क्या मैं सच में जानना चाहते है:

वहाँ एक गारंटी है कि सभी स्मृति अंत में कचरा एकत्र किया जाएगा और finalizer (नाशक) (वस्तु पर चलने संभालने कार्यक्रम अच्छी तरह से बाहर निकल गया है)। उदाहरण के लिए जब कोई अंततः बाहर निकलता है तो कोई मेमोरी दबाव वाला कोई एप्लीकेशन जीसी को सभी ऑब्जेक्ट्स को खोजने के लिए मजबूर करेगा और सुनिश्चित करेगा कि फाइनलाइज़र (विनाशक) को (स्थिर सदस्य चर सहित) कहा जाता है? http://www.c-sharpcorner.com/UploadFile/tkagarwal/MemoryManagementInNet11232005064832AM/MemoryManagementInNet.aspx

इसके अलावा, डिफ़ॉल्ट रूप से, अंतिम रूप तरीकों नहीं पहुंचा जा सकता वस्तुओं के लिए कहा जाता है नहीं कर रहे हैं एक आवेदन बाहर निकलता है तो यह है कि आवेदन जल्दी से समाप्त कर सकता है जब:

मैं इस पृष्ठ पर एक बोली मिला।

लेकिन मुझे यकीन नहीं है कि यह उद्धरण कितना आधिकारिक है। CriticalFinalizerObject

उत्तर

3

वहाँ एक गारंटी है कि सभी स्मृति अंत में कचरा एकत्र किया जाएगा और finalizer (नाशक) पर वस्तु को चलाने (कार्यक्रम अच्छी तरह से बाहर निकल गया यह सोचते हैं) है।

Object.Finalize प्रलेखन से नहीं। यह स्पष्ट है कि finalizers अगर

  • कुछ अन्य finalizers ठीक से समाप्त नहीं करते लागू नहीं किया जा सकता:

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

  • कुछ अन्य finalizers अधिक finalizable वस्तुओं को बनाने के लिए, यह असंभव सभी finalizable वस्तुओं को अंतिम रूप देने के लिए बनाने:

    क्रम शटडाउन के दौरान वस्तुओं को अंतिम रूप देने के लिए जारी है केवल जबकि finalizable वस्तुओं की संख्या घटना जारी है।अंतिम रूप या अंतिम रूप है, जिसकी ओवरराइड एक अपवाद फेंकता है तो

    , और क्रम , एक आवेदन है कि डिफ़ॉल्ट नीति को ओवरराइड करता है द्वारा होस्ट नहीं है:

  • कुछ अन्य finalizers अपवाद फेंक रनटाइम प्रक्रिया को समाप्त करता है और सक्रिय प्रयास-अंत में ब्लॉक या अंतिमकर्ता निष्पादित किए जाते हैं। फ़ाइनलाइज़र संसाधनों को मुक्त या नष्ट नहीं कर सकता है, तो यह व्यवहार प्रक्रिया अखंडता सुनिश्चित करता है।

कहा जा रहा है, वहाँ अधिक कारणों से आप जब तक अत्यंत आवश्यक होता finalizers का उपयोग नहीं करना चाहते हैं।

  • वे कचरा कलेक्टर धीमा (यहां तक ​​कि यह संभव है कि यह धीमा करने के लिए कर रही है नीचे इतना स्मृति के रूप में तेजी से के रूप में यह ऊपर प्रयोग किया जाता है नहीं पुन: दावा है)।
  • वे बहु-थ्रेडिंग मुद्दों को खेलने में लाते हुए एक और धागे पर दौड़ते हैं।
  • उन्हें निर्धारिती क्रम में निष्पादित नहीं किया गया है।
  • वे ऑब्जेक्ट्स को पुनर्जीवित कर सकते हैं जो पहले से ही अंतिम रूप दिए गए थे (और को तब तक अंतिम रूप दिया जाएगा जब तक स्पष्ट रूप से अंतिमकरण के लिए पुनः पंजीकृत नहीं किया गया हो)।
1

Spec की 1.6.7.6 का कहना है::

1.6.7.6 Destructors

एक नाशक एक सदस्य है कि कार्रवाई करने के लिए आवश्यक लागू करता है

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

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

कथन का उपयोग करके बेहतर विनाश के उद्देश्य के लिए दृष्टिकोण प्रदान करता है।

तो नहीं, इसकी गारंटी नहीं है कि उन्हें बुलाया जाता है।

0

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

+0

मुझे लगता है कि आपको इसके बारे में चिंता करने की ज़रूरत है, क्योंकि यदि आप अपने अंतिमकर्ता में कुछ महत्वपूर्ण काम करने की कोशिश करते हैं और इसे पूरा करने की अनुमति नहीं दी जा सकती है। –

+0

सामान्य रूप से, आप अपने अंतिमकर्ता में पर्याप्त मात्रा में काम नहीं करेंगे। – SLaks

+2

स्पष्ट रूप से; लेकिन यह मानना ​​तार्किक लगता है कि यही कारण है कि वह पूछ रहा है; जवाब यह है कि 'आईडीस्पोजेबल' का उपयोग करना आपकी कक्षा के निर्धारक सफाई को सुनिश्चित करने का सबसे अच्छा तरीका है। –

0

कोई गारंटी नहीं है।

यदि आपकी प्रक्रिया अच्छी तरह से कुछ परिभाषा के लिए अच्छी तरह से समाप्त हो जाती है तो गारंटी हो सकती है।

  • बिजली की विफलता
  • प्रक्रिया एक 'मुश्किल' या 'मजबूर' जिस तरह से
  • अप्रबंधित धागा फेंक बुला ओएस बाहर निकलें() फ़ंक्शन या एक फेंक में समाप्त: लेकिन वहाँ बहुत सी बातें अच्छी नहीं है कि हो सकता है अपवाद
  • System.Environment.FailFast करने के लिए कॉल, जो करता है:

MSDN: "एक प्रक्रिया समाप्त हो जाता है, लेकिन किसी भी सक्रिय कोशिश अंत में ब्लॉक या finalizers निष्पादित नहीं करता है।"

+2

'पावर विफलता' का बहुत मतलब है कि सभी मेमोरी रिलीज हो जाती है! –

+1

मैं समझता हूं कि जब बुरी चीजें होती हैं तो कुछ भी गारंटी नहीं दी जा सकती है। मैं सामान्य आवेदन निष्पादन के तहत गुरुत्वाकर्षण जानना चाहता हूं। जहां मुख्य() सामान्य रूप से कोई अपवाद नहीं निकलता है, कोई सिग्नल ने रोक नहीं लगाई है। –

+0

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

3

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

लेकिन प्रक्रिया समाप्त होने पर क्या होता है इससे परे आपको कोई गारंटी नहीं मिलती है।

अद्यतन:

इस संदर्भ को देखते हुए:

मैं एक कोड की समीक्षा मैं उसका कोड का किया था पर एक सहयोगी के साथ एक चर्चा कर रहा हूँ। उन्होंने जोर देकर कहा कि विनाशक वस्तु पर बुलाया जाने वाला है। मैं असहमत हूं (लेकिन मुझे यकीन नहीं है) और IDISposable का उपयोग पसंद करेंगे।

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

कोड के लिए जो "सामान्य" अप्रबंधित संसाधन (SqlConnection, TcpClient, आदि जैसी चीजें) को पहचानता है, IDISposable एक बेहतर विकल्प है। फिर आप जानते हैं कि जैसे ही निपटान() को इकट्ठा करने के लिए इंतजार करने की आवश्यकता के बजाय संसाधन को साफ किया जाएगा।यदि कोई भी निपटान() (जो आपके सहयोगी की चिंता की संभावना है) को कॉल करता है, तब तक जब तक आपका नया प्रकार एकत्र नहीं किया जा सकता है, तब तक अप्रबंधित संसाधन के लिए मूल प्रकार का उदाहरण आप लपेट रहे हैं, साथ ही इसे अंतिम रूप में भी एकत्र किया जा सकता है, और यह फ़ाइनलाइज़र है संसाधन जारी करेगा।

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

अगर अभी स्मृति यह कचरा एकत्र नहीं किया जाएगा एक वस्तु को

संदर्भ नहीं हो सकता है और करने के लिए एक संदर्भ है:

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

+0

और यहां तक ​​कि पहुंच योग्य वस्तुओं जीसीएड किया जा सकता है, जब तक इसे पहुंचने का एकमात्र तरीका "वीक रेफरेंस" ऑब्जेक्ट –

+0

के माध्यम से अपवाद नियम साबित करता है। –

+0

अगर मुझे सही याद है, जब किसी ऑब्जेक्ट को जीसी को अंतिम रूप देने की आवश्यकता होती है तो यह इस तरह बंद हो जाती है। यह ऑब्जेक्ट को छोड़ देता है, साथ ही सभी ऑब्जेक्ट्स को उस ऑब्जेक्ट द्वारा लगाया जाता है। इसलिए एक ऑब्जेक्ट जिसे अंतिम रूप देने की आवश्यकता होती है, ऑब्जेक्ट को अंतिम रूप देने तक स्मृति में वस्तुओं का एक बड़ा पेड़ रख सकता है। उसके बाद, ऑब्जेक्ट अभी भी अगले जीसी रन तक एकत्र नहीं किया जाएगा। तो यदि वस्तु Gen2 है और आपका ऐप चिकनी चल रहा है तो यह एक लंबा समय हो सकता है। – Glenn

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