2013-05-16 3 views
12

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

क्या जावा जीसी उन वस्तुओं को एकत्र करता है जो इसके संदर्भ को खो देते हैं, लेकिन इसके चर के संदर्भ में अभी भी संदर्भ है?

तो मान लीजिए कि मैं जाने SomeObject:

public class SomeObject { 
    public ObjectVar var; 

    public SomeObject() { 
     var = new ObjectVar(); 
    } 
} 

और मेरे कोड:

SomeObject obj1 = new SomeObject(); 
SomeObject obj2 = new SomeObject(); 
obj2.var = obj1.var; 
obj1 = null; 

तो obj1 के वर संदर्भ है, लेकिन obj1 अब कोई संदर्भ है। तो, क्या जीसी obj1 को नष्ट कर देगा, लेकिन var जीवित रखना होगा? (मुझे ऐसा लगता है, बस सुनिश्चित करना चाहता था)। धन्यवाद!

+0

जीसी के लिए मूल नियम यह है कि यदि कोई ऑब्जेक्ट जीसीइंग आपके प्रोग्राम को प्रभावित करेगा, तो ऐसा नहीं होता है। (जब तक आप विशेष उपकरण का उपयोग नहीं कर रहे हैं जो जीसी के बारे में परवाह करते हैं, लेकिन यदि आप इसका उपयोग कर रहे हैं, तो आप जान लेंगे।) –

+0

आप ["मिडलाइफ़ क्राइसिस"] (http: //blogs.msdn) के बारे में पढ़ना चाहेंगे। कॉम/बी/ricom/संग्रह/2003/12/04/41281.aspx)। – Mehrdad

उत्तर

12

यहाँ है कि क्या होने वाला है (देखें obj2 और पूर्व obj1.var जो अब obj2.var के रूप में संदर्भित है - नीचे टिप्पणी)

// obj1 and obj1.var get created 
SomeObject obj1 = new SomeObject(); 
// obj2 and obj2.var get created 
SomeObject obj2 = new SomeObject(); 
// old obj2.var becomes eligible for GC 
obj2.var = obj1.var; 
// obj1 becomes eligible for GC 
obj1 = null; 

अंत में, दो वस्तुओं है कि GCD नहीं मिलता है रहते हैं।

नोट: ObjectVar वर्ग SomeObject के एक गैर स्थिर भीतरी वर्ग जा रहा है, obj1.var के लिए एक संदर्भ रखते हुए भी चारों ओर obj1 रखेंगे की एक विशेष मामले में। ऐसा इसलिए है क्योंकि आंतरिक रूप से SomeObject.ObjectVar वर्ग में SomeObject का एक छुपा चर है, जो आंतरिक वर्ग की बाहरी वस्तु का संदर्भ देता है।

+0

ठीक है धन्यवाद! लेकिन अब मैं उलझन में हूं क्योंकि दो लोगों के पास अलग-अलग जवाब हैं। यदि ऑब्जेक्टवायर कुछ ऑब्जेक्ट का उप-वर्ग (या आंतरिक वर्ग) था, तो उपरोक्त कोड जीसी के लिए obj1 अपात्र बना देगा? – baekacaek

+1

@baekacaek ZyyaoWei की टिप्पणी केवल स्थिर आंतरिक कक्षाओं पर विचार की जाती है, इस मामले में यह वास्तव में कोई फर्क नहीं पड़ता। गैर स्थैतिक आंतरिक कक्षाएं और अज्ञात या नामित विधि-स्थानीय कक्षाएं मेजबान वस्तु को कचरा होने से रोक सकती हैं, लेकिन स्थैतिक आंतरिक कक्षाएं नहीं हो सकती हैं। – dasblinkenlight

+0

स्पष्टीकरण के लिए फिर से धन्यवाद, और त्वरित जवाब! – baekacaek

3

हां बिल्कुल।

याद रखें, var फ़ील्ड में आप जो स्टोर करते हैं, वह वास्तव में वस्तु के संदर्भ में वस्तु का संदर्भ है। तो जब जीसी obj1 एकत्र करता है, var वस्तु अछूता है ( छुआ नहीं किया जाना चाहिए), विशेष रूप से, क्योंकि यह obj2 से एक संदर्भ है, जो अभी भी जीवित है और अच्छी तरह से ..

+0

धन्यवाद, क्या वही लागू होता है यदि ऑब्जेक्टवायर कुछ ऑब्जेक्ट का आंतरिक वर्ग है? – baekacaek

+0

ठीक है इससे कोई फर्क नहीं पड़ता, क्योंकि इससे कोई फर्क नहीं पड़ता कि obj2 के उस ऑब्जेक्ट का संदर्भ क्या है। –

+2

यदि यह एक स्थिर आंतरिक वर्ग है, तो इससे कोई फर्क नहीं पड़ता। हालांकि, जब यह एक गैर-स्थैतिक आंतरिक वर्ग होता है, तो 'var' के बाहरी वर्ग में "पिछला संदर्भ" होता है, जो मालिक को जीवित रहने के लिए लंबे समय तक जीवित रख सकता है। – dasblinkenlight

0

हां - जैसा व्यवहार आप वर्णन करते हैं। कचरा संग्रह के लिए सामान्य नियम यह है कि ऑब्जेक्ट केवल योग्य हो जाते हैं जब आप किसी भी कठिन संदर्भ के माध्यम से उन तक नहीं पहुंच सकते हैं। इस प्रकार तक पहुंचने वाली कोई भी वस्तु इस प्रकार कभी कचरा नहीं एकत्र की जाएगी (मुलायम/कमजोर संदर्भों के अपवाद के साथ।)

0

बस शब्दों में कहें, यदि कोई वस्तु संदर्भों के पथ से अभी भी पहुंच योग्य है, तो यह संग्रह से बचने की गारंटी है। यदि ऐसा कोई रास्ता नहीं है, तो वस्तु को अब तक नहीं पहुंचा जा सकता है, और सुरक्षित रूप से एकत्र किया जा सकता है।

पहले दो लाइनों के बाद, स्मृति इस तरह दिखता है:

o1 --> SomeObj#1 --> ObjectVar#1 
o2 --> SomeObj#2 --> ObjectVar#2 

सभी 4 वस्तुओं, पहुँचा जा सकता है अगर एक कचरा संग्रहण इस समय होने के लिए गए थे, उनमें से कोई भी एकत्र किया जाएगा।

3 लाइन के बाद, यह इस तरह दिखता है:

o1 --> SomeObj#1 --> ObjectVar#1 
        ^
o2 --> SomeObj#2 ----- ObjectVar#2 

अब, केवल 3 वस्तुओं पहुँचा जा सकता है; कचरा कलेक्टर ऑब्जेक्टवायर # 2 को हटा सकता है।

4 लाइन के बाद, यह इस तरह दिखता है:

o1  SomeObj#1 --> ObjectVar#1 
        ^
o2 --> SomeObj#2 ----- ObjectVar#2 

केवल दो वस्तुओं अभी भी पहुंचा जा सकता है; कचरा कलेक्टर कुछ ओबीजे # 1 और ऑब्जेक्टवायर # 2 को हटा सकता है, लेकिन कुछ ओबीजे # 2 और ऑब्जेक्टवायर # 1 रखना चाहिए।

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