क्या कचरा संग्रहण के लिए स्थिर क्षेत्र खुले हैं?


95

केवल प्रोग्राम सेटअप में उपयोग किए जाने वाले काल्पनिक उपयोगिता वर्ग को देखते हुए:

class MyUtils {
   private static MyObject myObject = new MyObject();
   /*package*/static boolean doStuff(Params... params) {
       // do stuff with myObject and params...
   }
}

क्या myObject कचरा एकत्र किया जाएगा जब इसका उपयोग नहीं किया जा रहा है, या यह कार्यक्रम के जीवन के लिए चारों ओर रहेगा?

जवाबों:


112

क्लास में लोड होने के दौरान कचरा संग्रहण के लिए स्टेटिक चर का चुनाव नहीं किया जा सकता है। उन्हें तब एकत्र किया जा सकता है जब संबंधित वर्ग लोडर (जो इस वर्ग को लोड करने के लिए जिम्मेदार था) खुद कूड़े के लिए एकत्र किया जाता है।

की जाँच करें क्लासेस और इंटरफेस की JLS धारा 12.7 अनलोडिंग

एक वर्ग या इंटरफ़ेस को अनलोड किया जा सकता है यदि और केवल अगर उसके डिफाइनिंग क्लास लोडर को कचरा कलेक्टर द्वारा पुनः प्राप्त किया जा सकता है [...] बूटस्ट्रैप लोडर द्वारा लोड किए गए वर्ग और इंटरफेस अनलोड नहीं किए जा सकते हैं।


@bruno, आपके लिंक के अनुसार, क्या इसका मतलब यह है कि एक वर्ग लोडर प्रत्येक और हर वर्ग के लिए एक संदर्भ रखता है, भले ही कक्षा भरी हुई में स्थिर सदस्य न हों?
पचेरियर

@brunoconde, मुझे नहीं लगता कि यह वास्तव में सच है। वास्तव में कौन सा अनुच्छेद बताता है कि? (कृपया stackoverflow.com/questions/405364/… पर चर्चा जारी रखें )
Pacerier

जब वर्ग लोडर कचरा संग्रहण के लिए पात्र होगा। ?
रोहित बंडिल

@RohitBandil - जब यह पहुंच से बाहर है।
स्टीफन सी

55

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


1
क्या Classजिन वस्तुओं में कोई स्थिर चर नहीं होता है, उन्हें उनके क्लास लोडर द्वारा संदर्भित किया जाता है?
पचेरियर

14

यदि आप चाहते हैं कि एक स्थैतिक वस्तु का उपयोग स्थैतिक आरंभीकरण के लिए किया जाए, तो उसका निपटान किया जा सकता है, तो आप एक स्टेटिक इनिलाइज़र ब्लॉक का उपयोग कर सकते हैं, जैसे

class MyUtils {
   static
   {
      MyObject myObject = new MyObject();
      doStuff(myObject, params);
   }

   static boolean doStuff(MyObject myObject, Params... params) {
       // do stuff with myObject and params...
   }
}

चूंकि स्टेटिक इनिलाइज़र ब्लॉक एक विशेष प्रकार की स्टैटिक विधि है, myObject एक स्थानीय वैरिएबल है और ब्लॉक फिनिशिंग निष्पादित करने के बाद कचरा एकत्र किया जा सकता है।


13

myObject एक संदर्भ है और एक वस्तु नहीं है । जब कोई संदर्भ इंगित नहीं करता है, तो एक वस्तु स्वचालित रूप से कचरा एकत्र किया जाता है क्योंकि यह पहुंच से बाहर है।

तो एक स्थैतिक संदर्भ "myObject" के पीछे की वस्तु भी कचरा एकत्र किया जा सकता है यदि आप इसके साथ हस्तक्षेप करते हैं

myObject = null;

और इस वस्तु का कोई अन्य संदर्भ नहीं है।

हालाँकि स्थिर संदर्भ और चर आपके कार्यक्रम के जीवनकाल के लिए बने रहते हैं।


StackOverflow में आपका स्वागत है! nullके अंत में ऑब्जेक्ट सेट करना static blockएक व्यवहार्य विकल्प है। मेरे मामले में, हालांकि, वस्तु का जीवनकाल स्थिर ब्लॉक की तुलना में अधिक लंबा होना चाहिए। वस्तु की अंत-उपयोगिता बहुत ठोस नहीं थी; इस प्रकार मेरा कचरा संग्रहकर्ता के उपयोग के बारे में पूछना।
माइकल डियरडफ

7

मुझे लगता है कि यह आपके प्रश्न का उत्तर देता है - मूल रूप से तब तक नहीं जब तक कि वर्ग एक विशेष वर्ग लोडर से नहीं आता है और यह वर्ग को उतारता है।


0

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

तो इससे पहले कि आप अचानक private static MyGiantClass myGiantObject = new MyGiantClass() दो बार सोचने का फैसला करें क्योंकि मैंने कठिन तरीका सीखा है।

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