2012-07-19 19 views
6

के लिए योग्य ऑब्जेक्ट्स यह प्रश्न Kathy SierraSCJP 1.6 से लिया गया था। कचरा संग्रह के लिए कितने ऑब्जेक्ट योग्य हैं?कचरा संग्रह

कैथी सिएरा के उत्तर के अनुसार, यह C है। इसका मतलब है कि दो वस्तुएं कचरा संग्रह के लिए योग्य हैं। मैंने जवाब का स्पष्टीकरण दिया है। लेकिन c3 क्यों garbage collection (जीसी) के लिए योग्य नहीं है?

class CardBoard { 
    Short story = 200; 
    CardBoard go(CardBoard cb) { 
    cb = null; 
    return cb; 
} 

public static void main(String[] args) { 
    CardBoard c1 = new CardBoard(); 
    CardBoard c2 = new CardBoard(); 
    CardBoard c3 = c1.go(c2); 
    c1 = null; 
    // Do stuff 
} } 

जब // Do stuff तक पहुँच जाता है, कितने वस्तुओं जीसी लिए योग्य हैं?

  • A: 0
  • बी: 1
  • सी: 2
  • डी: संकलन में विफल रहता है
  • ई: यह पता करने के लिए
  • एफ संभव नहीं है: एक अपवाद कार्यावधि में फेंक दिया जाता है

उत्तर:

  • सी सही है। केवल एक कार्डबोर्ड ऑब्जेक्ट (सी 1) योग्य है, लेकिन इसमें Short रैपर ऑब्जेक्ट है जो योग्य भी है।
  • ए, बी, डी, ई, और एफ उपरोक्त के आधार पर गलत हैं। (वस्तुनिष्ठ 7,4)
+0

कड़ाई से बोलना 'सी 3' जीसी के लिए योग्य नहीं हो सकता है, क्योंकि * यह ऑब्जेक्ट नहीं है *। यह एक चर है एक वस्तु को इंगित कर सकता है। –

+0

सही उत्तर है [उन सभी] [http://stackoverflow.com/a/26645534/2711488) ... – Holger

उत्तर

6

कोई ऑब्जेक्ट कभी मौजूद नहीं है c3 अंक। कन्स्ट्रक्टर को केवल दो बार, दो ऑब्जेक्ट्स कहा जाता था, प्रत्येक एक को c1 और c2 द्वारा इंगित किया गया था। c3 सिर्फ एक संदर्भ है, जिसे कभी भी शून्य सूचक के अलावा कुछ भी नहीं दिया गया है।

संदर्भ c3, जो वर्तमान में शून्य को इंगित करता है, दायरे से बाहर नहीं जायेगा और मुख्य विधि के अंत में बंद ब्रेस तक पार होने तक ढेर से हटा दिया जाएगा।

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

+0

यह एक दिलचस्प बात है कि ऐसी चीजों पर चर्चा करने वाले बहुत सारे ट्यूटोरियल और व्यायाम हैं और वे सभी गलत हैं। सच्चाई यह है कि, जेवीएम को स्थानीय चर के दायरे का कोई ज्ञान नहीं है। अतीत में, यह अक्सर निहित था कि दायरे से बाहर होने के बावजूद कुछ संदर्भ साफ़ नहीं किए गए थे। आज, आप इस तथ्य से हैरान हो सकते हैं कि "दायरे में" होने के बावजूद ऑब्जेक्ट एकत्रित किया गया है, ["अंतिम() को जावा 8 में दृढ़ता से पहुंचने योग्य ऑब्जेक्ट पर कॉल किया गया है [] (http://stackoverflow.com/q/26642153/2711488) ... – Holger

+0

1) प्रश्न जावा 6 2 के बारे में है) '// डू स्टफ' के ज्ञान के बिना यह अनुमान लगाना असंभव है कि संकलक निष्कर्ष सी 2 की भविष्य की पहुंच के बारे में क्या कर सकता है। – Affe

+0

जावा 6 और जावा 8 के बीच नियम नहीं बदला है। आप यह भी नहीं रोक सकते कि वास्तविक जावा 6 कार्यान्वयन में ऐसी चीजें होती हैं, यह सिर्फ इतना है कि इस पर एसओ पर चर्चा नहीं हुई है। और यदि आप मानते हैं कि '// do stuff' में पहुंच योग्यता के लिए प्रासंगिक क्रियाएं हो सकती हैं, तो सही उत्तर यह होगा कि प्रश्न अपूर्ण है। यह सिर्फ और भी साबित होता है, इस तरह के सवाल कितने व्यर्थ हैं ... – Holger

4

c3null है, इसलिए वहाँ स्पष्ट रूप से कोई वस्तु कचरा संग्रहण के लिए पात्र है।

नोट केवल दो CardBoard ऑब्जेक्ट का निर्माण होगा कि, इन पंक्तियों पर दो:

CardBoard c1 = new CardBoard(); 
CardBoard c2 = new CardBoard(); 

और संदर्भ करतब दिखाने के बाद, उनमें से केवल एक संदर्भ के बिना है।

-1

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

7

के लाइन द्वारा इस रेखा के नीचे तोड़ दो: पर

CardBoard c1 = new CardBoard(); 

अब हम दो वस्तुओं है, CardBoardc1 अंक और Shortc1.story। न तो हम अब चार वस्तुओं, जिनमें से कोई भी जीसी के लिए उपलब्ध हैं

CardBoard c2 = new CardBoard(); 

ऊपर की ही तरह CardBoard पर c1 अंक और Short पर CardBoard अंकों की story चर के रूप में जीसी के लिए उपलब्ध है ...,।

CardBoard c3 = c1.go(c2); 

हम विधि जाने पर गत्ता c1 द्वारा की दिशा में रखे है, जो एक CardBoard वस्तु के लिए एक संदर्भ है c2 का मूल्य गुजर आह्वान। हम पैरामीटर को शून्य करते हैं, लेकिन जावा मूल्य से गुजरता है जिसका अर्थ है कि c2 परिवर्तनीय स्वयं अप्रभावित है। फिर हम शून्य पैरामीटर वापस कर देते हैं। c3null, c1 और c2 अप्रभावित हैं। हमारे पास अभी भी 4 वस्तुएं हैं, जिनमें से कोई भी जीसीडी नहीं हो सकता है।

c1 = null; 

हम शून्य c1CardBoard ऑब्जेक्ट जो c1 पहले इंगित करता है कि इसमें कुछ भी इंगित नहीं है, और यह जीसी'd हो सकता है। क्योंकि story उस CardBoard ऑब्जेक्ट के अंदर परिवर्तनीय Short पर इंगित करने वाली एकमात्र चीज है, और क्योंकि CardBoard ऑब्जेक्ट जीसी के लिए योग्य है, Short भी जीसी के लिए योग्य हो जाता है। यह हमें 4 ऑब्जेक्ट देता है, जिनमें से 2 जीसीड किया जा सकता है। जीसी के लिए पात्र वस्तुओं को पहले c1 और c1.story द्वारा संदर्भित किया गया है।

1

औपचारिक रूप से सही उत्तर यह है कि हम नहीं जानते हैं। और कारण है कि हम नहीं जानते कि इस लाइन है:

Short story = 200; 

यह निम्नलिखित बाइट कोड को संकलित करता है:

CardBoard(); 
Code: 
    0: aload_0 
    1: invokespecial #1     // Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: sipush  200 
    8: invokestatic #2     // Method java/lang/Short.valueOf:(S)Ljava/lang/Short; 
    11: putfield  #3     // Field story:Ljava/lang/Short; 
    14: return 

लाइन 8, यहाँ कुंजी है Short.valueOf(), जिनमें से एक बॉक्स्ड बराबर रिटर्न आदिम 200। के Short.valueOf() की जावाडोक पर नजर डालते हैं: सीमा -128 को 127, समावेशी में

इस विधि हमेशा कैश मूल्यों होगा, और इस सीमा के बाहर अन्य मूल्यों को संचित कर सकता।

200 "कैश कैश" श्रेणी से बाहर है, और इस प्रकार यह "कैश कैश" के अंतर्गत आता है। यदि यह कैश किया गया है, तो story का मान जीसी के लिए योग्य नहीं होगा जब इसमें CardBoard उदाहरण होगा। यदि यह कैश नहीं किया गया है, तो story पहुंच योग्य नहीं होगा और इस प्रकार जीसीड होगा।

सवाल स्पष्ट करने के लिए (और प्रस्तावित जवाब सही), कोड इस तरह संशोधन होना चाहिए:

Short story = new Short(200); 

अद्यतन:Short.valueOf() के लिए 1.6 Javadoc 1.8 संस्करण मैं उद्धृत के बजाय और अधिक गुप्त है , लेकिन एक ही तर्क लागू होता है: कोड को देखकर बताने का कोई तरीका नहीं है कि Short का नया या कैश किया गया उदाहरण वापस कर दिया जाएगा।

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