दिलचस्प पोस्ट
ईएफ कोड-पहले एक-से-एक रिश्ते: रिलेशनशिप में भूमिका * में बहुलता मान्य नहीं है बाइनरी कॉलेशन का क्या प्रभाव पड़ता है? Win32 एपीआई का उपयोग कर एक यूएसबी ड्राइव को सुरक्षित रूप से हटाएं? अजगर 3 और पायथन 3 एम निष्पादनयोग्य के बीच का अंतर लोचदार बीनस्टॉक उदाहरण के लिए एसएसएच फ़ील्ड मान को निर्धारित करने के लिए कैसे करें जो SQL सर्वर में (दशमलव, फ्लोट, इ) में परिवर्तित नहीं कर सकता Web.xml में applicationContext.xml फाइल के बजाय स्प्रिंग @ कॉन्फ़िगरेशन एनोटेटेड क्लास को कैसे रजिस्टर करें? अजगर में स्थानीय लोगों को संशोधित करना एंड्रॉइड एप्लिकेशन को कैसे आरंभ करें? मैं MySQL में गैर- ASCII वर्ण कैसे पा सकता हूं? UIWebView में प्रमाणीकरण चुनौती कैसे प्रदर्शित करें? हाइव: एक मुख्य तालिका पर incremental अपडेट करने का सर्वोत्तम तरीका सी कैसे गणना करता है पाप () और अन्य गणित कार्यों? XPath का उपयोग कर विशेषता प्राप्त करना विभिन्न प्रस्तावों के लिए उपयोग करने योग्य ड्रॉबल फ़ोल्डर सेट करना

जावा में कचरा कलेक्टर – एक ऑब्जेक्ट नल सेट करें

मान लीजिए, एक ट्री ऑब्जेक्ट है, जिसमें रूट ट्रीएनोड ऑब्जेक्ट है, और प्रत्येक ट्रीएनोड नेनोड और राइटनोड ऑब्जेक्ट्स छोड़ दिए हैं (जैसे कि बाइनरीट्री ऑब्जेक्ट)

अगर मैं कॉल करता हूं:

myTree = null; 

क्या वास्तव में पेड़ के अंदर संबंधित ट्रीएनोड ऑब्जेक्ट्स के साथ होता है? कचरा के रूप में अच्छी तरह एकत्र किया जाएगा, या मुझे पेड़ ऑब्जेक्ट के अंदर सभी संबंधित वस्तुओं को रिक्त करना होगा ??

वेब के समाधान से एकत्रित समाधान "जावा में कचरा कलेक्टर – एक ऑब्जेक्ट नल सेट करें"

जावा में कूड़ा संग्रह "पहुंचने" के आधार पर किया जाता है JLS इस प्रकार परिभाषित करता है:

"एक पहुंच योग्य ऑब्जेक्ट किसी भी ऑब्जेक्ट है जिसे किसी भी लाइव थ्रेड से किसी भी संभावित जारी गणना में पहुंचा जा सकता है।"

जब तक किसी ऑब्जेक्ट तक पहुंच योग्य * हो , तो यह कचरा संग्रहण के लिए पात्र नहीं है।

जेएलएस ने जावा कार्यान्वयन को छोड़ दिया है यह पता लगाने के लिए कि एक वस्तु सुलभ हो सकती है या नहीं। यदि कार्यान्वयन सुनिश्चित नहीं किया जा सकता है, तो यह एक सैद्धांतिक रूप से पहुंच योग्य वस्तु के पहुंच के रूप में पहुंचने योग्य है … और इसे एकत्रित नहीं किया जा सकता। (वास्तव में, जेएलएस एक कार्यान्वयन को कुछ भी एकत्रित करने की अनुमति नहीं देता है! कोई उचित कार्यान्वयन ऐसा नहीं करेगा।)

व्यवहार में, (रूढ़िवादी) पहुंच योग्यता का पता लगाने के द्वारा गणना की जाती है; क्लास (स्थिर) वेरिएबल्स और थ्रेड स्टैक्स पर स्थानीय वेरिएबल से शुरू होने वाले संदर्भों का पालन करके क्या देखा जा सकता है।


आपके प्रश्न के लिए इसका क्या मतलब है:

अगर मैं कॉल करता myTree = null; : myTree = null; क्या वास्तव में पेड़ के अंदर संबंधित ट्रीएनोड ऑब्जेक्ट्स के साथ होता है? कचरा के रूप में अच्छी तरह एकत्र किया जाएगा, या मुझे पेड़ ऑब्जेक्ट के अंदर सभी संबंधित वस्तुओं को रिक्त करना होगा ??

मान लीजिए कि myTree में myTree रूट के अंतिम शेष पहुंचने वाला संदर्भ है।

  1. कुछ भी तुरंत नहीं होता है
  2. यदि आंतरिक नोड पहले रूट रूट के जरिए केवल पहुंच योग्य थे , तो वे अब पहुंच योग्य नहीं हैं, और कचरा संग्रहण के लिए योग्य हैं। (इस मामले में, आंतरिक नोड्स के संदर्भ में null असाइन करना अनावश्यक है।)
  3. हालांकि, यदि आंतरिक नोड्स अन्य मार्गों के माध्यम से पहुंच योग्य हैं, तो वे संभवत: अभी तक पहुंच योग्य हैं, और इसलिए कचरा संग्रहण के लिए योग्य नहीं हैं। (इस मामले में, आंतरिक नोड्स के संदर्भ में null असाइन करना एक गलती है। आप एक डेटा संरचना को समाप्त कर रहे हैं, जो कुछ और बाद में उपयोग करने का प्रयास कर सकते हैं।)

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


तो आपको कचरा कलेक्टर की मदद करने के लिए null चीजों को कब करना चाहिए ?

जिन मामलों में आपको चिंता करने की ज़रूरत होती है, जब आप समझ सकते हैं कि कुछ कक्ष (स्थानीय, उदाहरण या वर्ग चर, या सरणी तत्व) में संदर्भ का उपयोग फिर से नहीं किया जाएगा, लेकिन संकलक और रनटाइम नहीं हो सकता! मामलों में लगभग तीन श्रेणियां होती हैं:

  1. वर्ग चर में ऑब्जेक्ट संदर्भ … जो (परिभाषा के द्वारा) कभी भी क्षेत्र से बाहर नहीं निकलते
  2. स्थानीय चर में ऑब्जेक्ट संदर्भ जो अभी भी क्षेत्र में हैं … लेकिन इसका उपयोग नहीं किया जाएगा। उदाहरण के लिए:

      public List<Pig> pigSquadron(boolean pigsMightFly) { List<Pig> airbornePigs = new ArrayList<Pig>(); while (...) { Pig piggy = new Pig(); ... if (pigsMightFly) { airbornePigs.add(piggy); } ... } return airbornePigs.size() > 0 ? airbornePigs : null; } 

    उपरोक्त में, हम जानते हैं कि यदि pigsMightFly गलत है, तो सूची वस्तु का उपयोग नहीं किया जाएगा लेकिन कोई मुख्यधारा जावा कम्पाइलर यह समझने की उम्मीद नहीं की जा सकती है।

  3. ऑब्जेक्ट संदर्भ उदाहरण चर में या सरणी कोशिकाओं में जहां डेटा स्ट्रक्चर इनरिएंटमेंट का मतलब है कि उनका उपयोग नहीं किया जाएगा। @ एडालोरो के स्टैक का उदाहरण इस का एक उदाहरण है।

यह ध्यान दिया जाना चाहिए कि कंपाइलर / रनटाइम कभी-कभी यह पता लगा सकते हैं कि एक स्क्वैश चर प्रभावी रूप से मृत है उदाहरण के लिए:

 public void method(...) { Object o = ... Object p = ... while (...) { // Do things to 'o' and 'p' } // No further references to 'o' // Do lots more things to 'p' } 

कुछ जावा कम्पाइलर / रनटाइम्स को यह पता लगा सकता है कि लूप समाप्त होने के बाद 'ओ' की आवश्यकता नहीं है, और वेरिएबल को मृत के रूप में मानते हैं।


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

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

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

ध्यान दें कि स्थानीय वेरिएबल्स के लिए जिसे आप सामान्य रूप से उन्हें null करने के लिए सेट नहीं करते हैं यदि विधि (या ब्लॉक) जल्द ही खत्म हो जाएगी।

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

कचरा कलेक्टर को ऑब्जेक्ट को निकालने के लिए, myTree बस कॉल करने के बाद gc() को कॉल करें

 myTree=null; System.gc(); 

ध्यान दें कि ऑब्जेक्ट को केवल तभी निकाला जा सकता है जब उसमें कोई अन्य संदर्भ इंगित न हो।

जावा में, आपको वस्तुओं को स्पष्ट रूप से सेट करने की आवश्यकता नहीं है ताकि उन्हें GC'd हो सकें। ऑब्जेक्ट्स जीसी के लिए योग्य हैं, जब इसके बारे में कोई संदर्भ नहीं है ( java.lang.ref.* वर्गों की उपेक्षा करना)।

एक ऑब्जेक्ट इकट्ठा होता है जब इसके बारे में कोई और संदर्भ नहीं होता है।

आपके मामले में, myTree (रूट नोड) द्वारा औपचारिक रूप से संदर्भित ऑब्जेक्ट द्वारा सीधे संदर्भित नोड्स एकत्र किए जाएंगे, और इसी तरह।

यह निश्चित रूप से ऐसा मामला नहीं है, यदि आपके पेड़ के बाहर नोड्स के लिए बकाया संदर्भ हैं उन संदर्भों को एक बार जब उन संदर्भों से बाहर निकलते हैं, वे उन लोगों को जीसीएड मिलेंगे (केवल कुछ के साथ वे देखेंगे)