2010-01-20 15 views
9

जब एक संपत्ति आंतरिक श्रेणी के रूप में अज्ञात आंतरिक वर्ग का उपयोग करते हैं तो ऑब्जेक्ट लाइफ चक्र में किस बिंदु पर कक्षा कचरा एकत्र किया जाता है? युक्त कक्षा (सेटिंग्स नोड) के बाद पुनः दावा किया गया है? क्या मुझे स्पष्ट श्रेणी (सेटिंग्स नोड) के अंतिमकर्ता में PropertyChangeListener को स्पष्ट रूप से हटा देना चाहिए?जावा - बेनामी इनर क्लास लाइफ साइकिल

public class SettingsNode extends AbstractNode 
{ 
    public SettingsNode(Project project, ProjectSettings projectSettings) 
     throws IntrospectionException 
    { 
     // use an anonymous inner class to listen for changes 
     projectSettings.addPropertyChangeListener(ProjectSettings.PROP_NAME, 
      new PropertyChangeListener() 
      { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) 
       { 
        // handle event 
       } 
      }); 
    } 
} 
+0

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

उत्तर

7

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

इस विशेष मामले में, यह तब होगा जब projectSettings या तो removePropertyListener() करता है या स्वयं कचरा एकत्र होता है।

क्योंकि projectSettings गुमनाम आंतरिक वर्ग का संदर्भ देता है और क्योंकि आंतरिक वर्ग अपनी कक्षा का संदर्भ देता है, जिसका अर्थ है कि युक्त कक्षा कम से कम आंतरिक कक्षा के रूप में भी रहती है।

+0

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

+0

अब आपने यह कहा है कि मुझे अब और नहीं करना है :) आप बिल्कुल सही हैं, और धन्यवाद; लेकिन मुझे उम्मीद है कि हमारे पाठकों में से कोई भी कोड लिखता है जो इस व्यवहार पर निर्भर करता है। –

2

आप प्रोजेक्ट सेटिंग ऑब्जेक्ट में प्रॉपर्टी चेंज लिस्टनर क्लास जोड़ रहे हैं। जब तक ProjectSettings इसका संदर्भ देता है तब तक PropertyChangeListener को तब तक एकत्र नहीं किया जाएगा।

2

उदाहरण में आपने दोनों सेटिंग्स नोड दिखाए हैं और श्रोता को पुन: दावा नहीं किया जा सकता है जब तक कि परियोजना सेटिंग्स को पुनः दावा नहीं किया जाता है।

आपको श्रोता को स्पष्ट रूप से हटाने की आवश्यकता होगी लेकिन आपको शायद अंतिम रूप से कहीं अधिक विश्वसनीय दिखना चाहिए।

PropertyNangeListener हटा दिए जाने तक सेटिंग्स नोड पुनः प्राप्त नहीं किया जाएगा। श्रोताओं के लिए अज्ञात वर्गों का उपयोग करना यह स्मृति रिसाव का एक आम कारण है।

संपादित एलेक्स बी से सवाल follwing:

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

+0

@Aaron: क्या आप एक उदाहरण दे सकते हैं जहां स्मृति रिसाव होगी? –

+0

@Alex: प्रश्न में कोड वास्तव में मेमोरी लीक के लिए एक उदाहरण है यदि यह श्रोता को हटा नहीं देता है जब 'सेटिंग्स नोड' की आवश्यकता नहीं होती है। कार्ल का जवाब बताता है कि ऐसा होता है। – x4u

0

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

वास्तव में आश्चर्यचकित क्यों कमजोर श्रोता पंजीकरण में स्विंग नहीं बनाया गया है। शायद आप स्रोत फोर्ज में कुछ ओपन सोर्स आज़मा सकते हैं?

1

यह प्रश्न काफी दिनांकित है।

हालांकि, मैं यहां अधिकांश उत्तरों से सहमत नहीं हूं।

श्रोता को स्पष्ट रूप से हटाने की आवश्यकता नहीं है। इस मामले में, आंतरिक वर्ग PropertyChangeListener ऑब्जेक्ट तब तक लाइव रहेगा जब तक कि युक्त इंस्टेंस सेटिंग्स नोड को एकत्रित किया जाता है।

आप वास्तव में PropertyChangeListener ऑब्जेक्ट को नहीं हटा सकते हैं क्योंकि इसके लिए कोई संदर्भ नहीं रखा गया है।

हालांकि यह सच है कि PropertyChangeListener ऑब्जेक्ट में इसके ऑब्जेक्ट सेटिंग्स नोड का संदर्भ है, जो उस ऑब्जेक्ट को डी-रेफरेंस और कचरा एकत्रित करने से नहीं रोकता है।

एक बार जब ऑब्जेक्ट को संदर्भित किया जा रहा है, तो सेटिंग नोड द्वारा निहित सभी ऑब्जेक्ट्स "अलगाव का द्वीप" बन जाता है। उन सभी को कचरा इकट्ठा किया जाएगा।

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