2013-03-10 2 views
17

मैं कचरा संग्रह के बारे में पढ़ रहा हूं और जब मैं स्ट्रिंग शाब्दिक कचरा संग्रह की खोज करता हूं तो मुझे भ्रमित खोज परिणाम मिल रहा है।स्ट्रिंग अक्षर का कचरा संग्रह

मैं निम्नलिखित बातों पर स्पष्टीकरण की जरूरत है:

  1. एक स्ट्रिंग संकलन समय पर शाब्दिक रूप में परिभाषित किया गया है, तो [उदाहरण के लिए: String str = "java"] एकत्र तो यह कचरा हो जाएगा?

  2. यदि आंतरिक विधि का उपयोग करें [उदा: String str = new String("java").intern()] तो क्या यह कचरा इकट्ठा होगा? इसके अलावा स्ट्रिंग शाब्दिक से बिंदु 1 में अलग-अलग व्यवहार किया जाएगा।

  3. कुछ स्थानों पर यह उल्लेख किया गया है कि शाब्दिक कचरे को केवल तभी एकत्र किया जाएगा जब String कक्षा को उतार दिया जाएगा? क्या यह समझ में आता है क्योंकि मुझे नहीं लगता कि String कक्षा कभी भी अनलोड हो जाएगी।

+2

1 - http://stackoverflow.com/questions/2202162/garbage-collection-and-strings; 2 - http://stackoverflow.com/questions/6470651/creating-a-memory-leak-with-java; 3 - स्ट्रिंग ए = न्यू स्ट्रिंग ("asd") -> "ए" संदर्भ कचरा एकत्रित किया जाएगा, लेकिन केवल "asd" और "asd" का संदर्भ हमेशा के लिए होगा। – user1050755

+0

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

उत्तर

18

यदि किसी स्ट्रिंग को संकलन समय पर शाब्दिक के रूप में परिभाषित किया गया है [उदा: String str = "java";] तो क्या यह कचरा एकत्रित होगा?

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

कोड ऑब्जेक्ट्स पहुंचने योग्य नहीं है, लेकिन केवल तभी जब वे गतिशील रूप से लोड हो जाएं ... और उनका क्लासलोडर नष्ट हो गया है।

यदि मैं आंतरिक विधि का उपयोग करता हूं [ई।जी: String str = new String("java").intern()] तो क्या यह कचरा इकट्ठा होगा?

वस्तु intern कॉल द्वारा दिया एक ही वस्तु है कि "java" स्ट्रिंग शाब्दिक प्रतिनिधित्व किया जाएगा। ("java" शाब्दिक समय वर्ग लोड हो रहा है पर प्रशिक्षु है। आप तो प्रशिक्षु अपने कोड स्निपेट में नवनिर्मित String वस्तु है, यह देखने और वापस आ जाएगी जब पहले से "java" स्ट्रिंग प्रशिक्षु।)

हालांकि, तार उस के साथ समान नहीं हैं प्रशिक्षु स्ट्रिंग अक्षर पहुंचने के बाद कचरा इकट्ठा किया जा सकता है। PermGen space कचरा सभी हालिया हॉटस्पॉट JVMs पर एकत्रित है। (पहले जावा 8 ... जो PermGen पूरी तरह से चला जाता है के लिए।)

यह भी बिंदु में स्ट्रिंग शाब्दिक से अलग ढंग से व्यवहार किया जाएगा 1.

नहीं ... क्योंकि यह एक ही वस्तु के रूप में है स्ट्रिंग शाब्दिक।

और वास्तव में, एक बार जब आप समझते हैं कि क्या हो रहा है, तो यह स्पष्ट है कि स्ट्रिंग अक्षर का विशेष रूप से इलाज नहीं किया जाता है। यह सिर्फ "पहुँचता" शासन के एक आवेदन पत्र है ...

कुछ स्थानों यह उल्लेख किया गया है कि शाब्दिक कचरा केवल एकत्र किया जाएगा जब String वर्ग उतार दिया जाएगा? क्या यह समझ में आता है क्योंकि मुझे नहीं लगता कि String कक्षा कभी भी अनलोड नहीं की जाएगी।

आप सही हैं। यह समझ में नहीं आता है। सूत्रों ने कहा कि गलत हैं। (यदि आप एक यूआरएल पोस्ट करते हैं तो यह सहायक होगा ताकि हम पढ़ सकें कि वे खुद के लिए क्या कह रहे हैं ...)

+1

# 1 के लिए, जब आप कोड ऑब्जेक्ट्स कहते हैं जिसमें स्ट्रिंग अक्षर के संदर्भ होते हैं, तो आप किस बात का जिक्र कर रहे हैं? – Mercenary

+4

कोड ऑब्जेक्ट्स (बाइटकोड या देशी संकलित) में कहीं भी ऐसे निर्देश होंगे जिन्हें स्ट्रिंग ऑब्जेक्ट के संदर्भ को लाने की आवश्यकता है जो शाब्दिक से मेल खाते हैं। या तो संदर्भ कोड में ही एम्बेड किया गया है, या यह कोड से जुड़े एक निजी फ्रेम में संग्रहीत है। किसी भी तरह से, संदर्भ "पहुंचने योग्य" है जब तक कि कोड * निष्पादित किया जा सके। –

+0

धन्यवाद। और, जेवीएम में विधि क्षेत्र का स्ट्रिंग इंटर्न पूल हिस्सा है? – Mercenary

9

सामान्य परिस्थितियों में, स्ट्रिंग शाब्दिक और कक्षाओं सभी JVM के स्थायी पीढ़ी ("PermGen") में आवंटित किए जाते हैं, और आमतौर पर कभी एकत्र नहीं किया जाएगा। स्ट्रिंग्स जो इंटर्न किए गए हैं (उदाहरण के लिए mystring.intern()) परमिट में String कक्षा के स्वामित्व वाले मेमोरी पूल में संग्रहीत हैं, और यह एक बार ऐसा था कि आक्रामक इंटर्निंग स्पेस रिसाव का कारण बन सकती है क्योंकि स्ट्रिंग पूल ने प्रत्येक स्ट्रिंग का संदर्भ रखा है, भले ही कोई अन्य संदर्भ मौजूद नहीं था। स्पष्ट रूप से यह अब सत्य नहीं है, कम से कम जेडीके 1.6 (देखें, उदाहरण के लिए, here)।

परमिट पर अधिक के लिए, this विषय का एक सभ्य अवलोकन है। (ध्यान दें: वह लिंक किसी उत्पाद से जुड़े ब्लॉग पर जाता है। मेरे पास ब्लॉग, कंपनी या उत्पाद के साथ कोई संबंध नहीं है, लेकिन ब्लॉग एंट्री उपयोगी है और उत्पाद के साथ बहुत कुछ नहीं है।)

+2

यह गलत है। PermGen अंतरिक्ष >><< कचरा एकत्रित है। –

+0

आप बिल्कुल सही हैं। मेरा इरादा सिर्फ यह कहना था कि परमजन में आवंटित डेटा को सामान्य परिस्थितियों में जीसी नहीं मिलेगा, लेकिन मैंने गलतफहमी की। थोड़ा सा rephrased। – jacobm

+0

दरअसल, गहराई से खुदाई करते हुए, मैंने पाया कि अब यह सच नहीं है कि आंतरिक तारों को कचरा नहीं मिला है। (यह परमजन स्पेस की वजह से नहीं है, यह 'स्ट्रिंग # इंटर्न' के कार्यान्वयन के कारण है।) इसे प्रतिबिंबित करने के लिए मेरा उत्तर बदलना। – jacobm

0
  1. जब तक कार्यक्रम स्मृति में होता है तब तक शाब्दिक स्ट्रिंग स्मृति में रहेगी।
  2. str कचरा इकट्ठा किया जाएगा, लेकिन शाब्दिक इसे बनाया जाएगा।
  3. यह सही समझ में आता है, क्योंकि प्रोग्राम अनलोड होने पर स्ट्रिंग क्लास को अनलोड किया जाता है।
+0

क्या आप मुझे एक उदाहरण दे सकते हैं जहां स्ट्रिंग को अनलोड किया जा सकता है? जैसा कि मेरा मानना ​​है कि स्ट्रिंग अक्षर का प्रयोग जावा कक्षाओं के भीतर भी किया जाना चाहिए और स्ट्रिंग अक्षर स्थिरांक हैं, इसलिए मेरे ज्ञान के अनुसार अनलोडिंग को क्लासलोडर के अनलोडिंग की आवश्यकता हो सकती है। क्या आप सहमत हैं? – Lokesh

+0

एक स्ट्रिंग अक्षरशः मेरे ज्ञान को प्रोग्रामिंग रूप से अनलोड नहीं किया जा सकता है। प्रोग्राम समाप्त होने पर उन्हें अनलोड किया जाएगा, या नष्ट कर दिया जाएगा। – fredrik

+1

@ फ़्रेड्रिक - यदि वे गतिशील रूप से लोड किए गए वर्ग को अनलोड किया गया है तो वे भी कचरा इकट्ठा किया जा सकता है। और यह तब हो सकता है जब JVM सामान्य रूप से चल रहा है। –

-3

intern() विधि स्ट्रिंग पूल में ऑब्जेक्ट की उपलब्धता की जांच करता है। यदि ऑब्जेक्ट/शाब्दिक उपलब्ध है तो इसका संदर्भ वापस कर दिया जाएगा। यदि पूल में शाब्दिक नहीं है तो वस्तु को परम क्षेत्र (स्ट्रिंग पूल) में लोड किया जाता है और फिर इसका संदर्भ वापस आ जाएगा। हमें intern() विधि को समझदारी से उपयोग करना होगा।

+0

शाब्दिक हमेशा परिभाषा के अनुसार पूल में होता है। – EJP

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