क्या ईवेंट हैंडलर कचरा संग्रहण को होने से रोकते हैं?


183

अगर मेरे पास निम्नलिखित कोड है:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

क्या पक्का कचरा एकत्र किया जाएगा? या फिर जब भी ये घटनाएँ घटित होती हैं, तब भी ये चारों ओर लटकती रहेंगी? कचरा संग्रहण की अनुमति देने के लिए क्या मुझे निम्नलिखित करने की आवश्यकता होगी?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;

11
मैं इस प्रश्न में रुचि रखने वाले पाठकों को अस्थायी रूप से सुझाव देने जा रहा हूं कि यह हल्के घटनाओं / कमजोर घटना पैटर्न से परिचित होने के योग्य हो सकता है, जो कि कचरा संग्रह को होने से नहीं रोकता है। इस विषय के लिए एक अच्छा SO बूटस्ट्रैप है stackoverflow.com/questions/185931/…
fostandy

20
पश्चाताप के लिए ध्यान दें: संदर्भ को अशक्त करने के लिए संदर्भ के दायरे को एक पंक्ति द्वारा बढ़ाकर बस कचरा कलेक्टर को विलंबित किया जाता है। .NET VB6 नहीं है।
जॉन सॉन्डर्स 3

जवाबों:


207

विशिष्ट प्रश्न के लिए "विल क्लेकस कचरा एकत्र किया जाएगा": घटना की सदस्यता का पिकासों (प्रकाशक के रूप में) के संग्रह पर कोई प्रभाव नहीं पड़ता है।

सामान्य रूप से GC के लिए (विशेष रूप से, लक्ष्य): यह निर्भर करता है कि MyFunction स्थिर है या उदाहरण-आधारित।

इंस्टैंट विधि के लिए एक प्रतिनिधि (जैसे एक इवेंट सदस्यता) उदाहरण के लिए एक संदर्भ शामिल है। तो हाँ, एक घटना सदस्यता जीसी को रोक देगा। हालाँकि, जैसे ही ईवेंट प्रकाशित होने वाली वस्तु (ऊपर पिकास) संग्रह के लिए योग्य है, यह एक समस्या बन जाती है।

ध्यान दें कि यह एक तरफ़ा है; अगर हमारे पास है:

publisher.SomeEvent += target.SomeHandler;

तब "प्रकाशक" "लक्ष्य" को जीवित रखेगा, लेकिन "लक्ष्य" "प्रकाशक" को जीवित नहीं रखेगा।

तो नहीं: यदि pClass वैसे भी एकत्र किया जा रहा है, तो श्रोताओं को सदस्यता समाप्त करने की कोई आवश्यकता नहीं है। हालाँकि, यदि pClass लंबे समय तक जीवित रहा (MyFunction के साथ उदाहरण से अधिक), तो pClass उस उदाहरण को जीवित रख सकता है, इसलिए यदि आप लक्ष्य को एकत्र करना चाहते हैं , तो इसे सदस्यता समाप्त करना आवश्यक होगा

हालांकि, इस कारण से, स्थैतिक घटनाएँ बहुत खतरनाक होती हैं, जिनका उपयोग उदाहरण-आधारित हैंडलर के साथ किया जाता है।


6
ठीक है, अगर सवाल है "क्या कचरा इकट्ठा किया जाएगा", तो जवाब "यह निर्भर करता है कि क्या ..." वास्तव में सही नहीं है। यह किसी भी चीज पर निर्भर नहीं करता है, क्योंकि मार्क खुद आगे और नीचे नोट करता है।
Tor Haugen

@Tor - निष्पक्ष पर्याप्त - मैं स्पष्ट करता हूँ
मार्क Gravell

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

एक महान जवाब क्योंकि यह प्रश्न के दूसरे आधे हिस्से को भी संबोधित करता है (जो कि नहीं पूछा गया था): प्रकाशक ग्राहक को GC'd होने से रोक देगा।
बॉब सैमर्स

हां, और जैसा @ @Sammers ने कहा, यह वास्तव में एक समस्या हो सकती है यदि एक फॉर्म / विंडो की तरह एक लघु-जीवन उदाहरण, एक सिंगलटन जैसी लंबी-जीवन सेवा की सदस्यता ले रहा है जो उदाहरण के लिए डेटा प्रदान करता है: सिंगलटन तब एक संदर्भ रखता है , और वस्तुओं को स्मृति में रखा जाता है, तब भी जब हम सोचते हैं कि वे अनलोड हैं! इसलिए घटनाओं का उपयोग करते समय बहुत सतर्क रहें। हमने अपने बड़े सॉफ़्टवेयर के लिए घटनाओं के साथ दुर्व्यवहार किया, और बाद में इसे हल करना बहुत कठिन है।
एलो

9

हां, क्‍लैक्‍स को इकट्ठा किया जाएगा। घटना की सदस्यता का मतलब यह नहीं है कि कोई संदर्भ pClass के लिए मौजूद है।

ऐसा नहीं है, आपको क्‍लास एकत्र करने के लिए क्‍लास के लिए हैंडलर को अलग नहीं करना पड़ेगा।


8

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

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


0

pClassकचरा एकत्र किया जाएगा। हालाँकि, यदि ऊपर कोड स्निपेट किसी अन्य वर्ग के अंदर है, तो यदि आप सेट नहीं करते हैं तो उस वर्ग का उदाहरण साफ़ नहीं किया जा सकता pClassहै null

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.