46

कक्षा उदाहरणों के एकत्रीकरण को देखते हुए जो जटिल, परिपत्र, फैशन में एक दूसरे को संदर्भित करते हैं: क्या यह संभव है कि कचरा कलेक्टर इन वस्तुओं को मुक्त करने में सक्षम न हो?जावा में परिपत्र संदर्भ

मुझे अजीब बात यह है कि यह अतीत में जेवीएम में एक मुद्दा है, लेकिन सोचा यह साल पहले हल किया गया था। फिर भी, झट में कुछ जांच ने एक सर्कुलर संदर्भ को एक स्मृति रिसाव का कारण बताया है जिसका अब मुझे सामना करना पड़ रहा है।

नोट: मैं हमेशा इस धारणा के तहत रहा हूं कि जेवीएम सर्कुलर संदर्भों को हल करने और स्मृति से "कचरे के द्वीप" को मुक्त करने में सक्षम था। हालांकि, मैं यह प्रश्न सिर्फ यह देखने के लिए प्रस्तुत कर रहा हूं कि किसी को कोई अपवाद मिला है या नहीं।

उत्तर

40

केवल एक बहुत ही निष्क्रिय कार्यान्वयन में परिपत्र संदर्भों में समस्या होगी। विकिपीडिया के पास विभिन्न जीसी एल्गोरिदम पर article अच्छा है। यदि आप वास्तव में और जानना चाहते हैं, तो कोशिश करें (अमेज़ॅन) Garbage Collection: Algorithms for Automatic Dynamic Memory Management। जावा के पास 1.2 से अच्छा कचरा कलेक्टर है और 1.5 और जावा 6 में असाधारण रूप से अच्छा है।

जीसी में सुधार के लिए कठिन हिस्सा विराम और संदर्भ को कम करता है, सर्कुलर संदर्भ जैसी बुनियादी चीजें नहीं।

21

कचरा कलेक्टर जानता है कि रूट ऑब्जेक्ट्स कहां हैं: स्टेटिक्स, स्टैक पर स्थानीय, आदि और यदि ऑब्जेक्ट रूट से पहुंच योग्य नहीं हैं तो उन्हें पुनः दावा किया जाएगा। यदि वे पहुंच योग्य हैं, तो उन्हें चारों ओर रहना होगा।

0

कचरा कलेक्टर सॉफ्टवेयर का एक बेहद परिष्कृत टुकड़ा है - इसका परीक्षण एक विशाल जेकेसी परीक्षण सूट में किया गया है। यह सही नहीं है लेकिन एक बहुत अच्छा मौका है कि जब तक जावा कंपाइलर (जावा) आपके सभी वर्गों को संकलित करेगा और JVM इसे तुरंत चालू करेगा, तो आपको अच्छा होना चाहिए।

फिर फिर, यदि आप इस ऑब्जेक्ट ग्राफ़ की जड़ के संदर्भ धारण कर रहे हैं, तो स्मृति मुक्त नहीं होगी लेकिन यदि आप जानते हैं कि आप क्या कर रहे हैं, तो आपको ठीक होना चाहिए।

3

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

2

बस बढ़ाना क्या पहले से ही कहा गया है:

आवेदन मैं छह साल हाल ही में जावा 1.6 के लिए जावा 1.4 से बदल के लिए कार्य कर रहे हैं, और हम यह जान लिया है कि हम स्थिर जोड़ने के लिए मिला है उन चीज़ों के संदर्भ जिन्हें हमने महसूस नहीं किया था, पहले कचरा इकट्ठा करने योग्य थे। हमें पहले स्थिर संदर्भ की आवश्यकता नहीं थी क्योंकि कचरा कलेक्टर चूसने के लिए इस्तेमाल होता था, और यह अब इतना बेहतर है।

+0

यदि यह पहले नहीं पहुंचा जा सका, तो आप कैसे जानते थे कि यह दूर चला गया? मुझे आश्चर्य है कि क्या कोई प्रकार का लिंक है जिसके बारे में आप सोच नहीं रहे हैं जिससे सिस्टम इसे बनाए रख सकता है। एक धागा या श्रोता। –

+0

आप कैसे जानते थे कि वस्तुओं को कचरा इकट्ठा किया गया था या नहीं जब आपने उन सभी संदर्भों को छोड़ दिया होगा? क्या वे कमजोर संदर्भ थे या क्या आपके पास जेएनआई के माध्यम से उनके लिए एक लिंक था या क्या यह किसी प्रकार का लाइव ऑब्जेक्ट था जिसे अभी भी सक्रिय किया जा सकता है? – Brian

+0

समस्या यह थी कि जब हम इसका संदर्भ देने गए, तो यह चला गया। मैं सटीक विवरण भूल जाता हूं क्योंकि यह कुछ महीने पहले था, लेकिन मुझे लगता है कि हम इसे आरएमआई विधि के माध्यम से बुला रहे थे। –

2

संदर्भ गणना जीसी इस मुद्दे के लिए कुख्यात हैं। विशेष रूप से, सन जेवीएम जीसी की गणना करने वाले संदर्भ का उपयोग नहीं करता है।

यदि ऑब्जेक्ट ढेर की जड़ से नहीं पहुंच सकता है (आमतौर पर, कम से कम, क्लासलोडर्स के माध्यम से यदि कुछ और नहीं है, तो ऑब्जेक्ट्स नष्ट हो जाएंगे क्योंकि उन्हें एक सामान्य जावा जीसी के दौरान प्रतिलिपि नहीं बनाई जाती है ढेर।

+0

संदर्भ गणना एक निष्पक्ष कार्यान्वयन का एक बहुत अच्छा उदाहरण है। –

+0

असल में, यह एक चालाक कार्यान्वयन है, यह भी एक आसान कार्यान्वयन है, और इसकी इसकी सीमाएं होने पर, यह एक व्यवहार्य एल्गोरिदम है, खासकर स्मृति बाधित वातावरण में। –

+0

मै मैकोज़ विकास पर पढ़ रहा हूं और स्पष्ट रूप से ऑब्जेक्टिव सी संदर्भ गणना आधारित कचरा संग्रह के साथ-साथ जावा की तरह एक और परिष्कृत योजना का समर्थन करता है। –

3

जावा विनिर्देश का कहना है कि कचरा कलेक्टर कचरा अपने वस्तु ही अगर यह किसी भी धागे से पहुंच योग्य नहीं है एकत्र कर सकते हैं।

पहुंच योग्य का मतलब है एक संदर्भ, या संदर्भ की श्रृंखला से सुराग नहीं है ए टू बी, और सी, डी, ... जेड के माध्यम से जा सकते हैं, इसकी सभी परवाह है।

जेवीएम चीजों को इकट्ठा नहीं कर रहा है 2000 से मेरे लिए कोई समस्या नहीं है, लेकिन आपका माइलेज भिन्न हो सकता है।

युक्ति: जावा क्रमबद्धता ऑब्जेक्ट जाल हस्तांतरण कुशल बनाने के लिए वस्तुओं को कैश करती है। यदि आपके पास कई बड़ी, क्षणिक वस्तुएं हैं, और आपकी सभी मेमोरी हो रही है, तो अपने कैश को साफ़ करने के लिए अपने सीरियलज़र को रीसेट करें।

4

यदि मुझे सही याद है, तो विनिर्देशों के मुताबिक, केवल जेवीएम (कुछ भी पहुंच योग्य नहीं) एकत्र नहीं कर सकता है, यह नहीं कि वह क्या एकत्र करेगा।

जब तक आप रीयल-टाइम JVMs के साथ काम नहीं कर रहे हैं, तो अधिकांश आधुनिक कचरा कलेक्टर जटिल संदर्भ संरचनाओं को संभालने में सक्षम होना चाहिए और "सबग्राफ" को पहचानने में सक्षम होना चाहिए जिन्हें सुरक्षित रूप से समाप्त किया जा सकता है। ऐसा करने की दक्षता, विलंबता और संभावना समय के साथ सुधारती है क्योंकि अधिक शोध विचार मानक (अनुसंधान के बजाय) वीएम में अपना रास्ता बनाते हैं।

+1

और बिंदु पर जोर देने के लिए, एक जेवीएम जो अनंत ढेर मानता है और कचरा इकट्ठा नहीं करता है पूरी तरह से अनुपालन (हालांकि अक्षम है ;-) – ddimitrov

11

रयान, Circular References in Java पर आपकी टिप्पणी के आधार पर, आप कक्षा से ऑब्जेक्ट्स को संदर्भित करने के जाल में गिर गए, जो शायद बूटस्ट्रैप/सिस्टम क्लासलोडर द्वारा लोड किया गया था। प्रत्येक वर्ग को क्लासलोडर द्वारा संदर्भित किया जाता है जो वर्ग को लोड करता है, और इस प्रकार केवल कचरा-संग्रहित किया जा सकता है यदि क्लासलोडर अब तक पहुंच योग्य नहीं है। पकड़ यह है कि बूटस्ट्रैप/सिस्टम क्लासलोडर कभी कचरा इकट्ठा नहीं होता है, इसलिए, सिस्टम क्लासलोडर द्वारा लोड की गई कक्षाओं से पहुंचने योग्य वस्तुएं कचरा-संग्रहित नहीं हो सकती हैं।

इस व्यवहार के लिए तर्क जेएलएस में समझाया गया है। उदाहरण के लिए, तीसरा संस्करण 12.7 http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

+0

असल में, हमने सोचा कि हमने यह पता लगाया है लेकिन दुर्भाग्यवश यह अब ऐसा लगता है कि हमारे पास यह नहीं है । लेकिन हाँ, यह एक संभावना है जिसे हमें तलाशना चाहिए। –

2

एक परिपत्र संदर्भ तब होता है जब एक वस्तु दूसरे को संदर्भित करती है, और दूसरा व्यक्ति पहली वस्तु को संदर्भित करता है। उदाहरण के लिए:

class A { 
private B b; 

public void setB(B b) { 
    this.b = b; 
} 
} 

class B { 
private A a; 

public void setA(A a) { 
    this.a = a; 
} 
} 

public class Main { 
public static void main(String[] args) { 
    A one = new A(); 
    B two = new B(); 

    // Make the objects refer to each other (creates a circular reference) 
    one.setB(two); 
    two.setA(one); 

    // Throw away the references from the main method; the two objects are 
    // still referring to each other 
    one = null; 
    two = null; 
} 
} 

जावा के कचरा कलेक्टर बहुत चालाक अगर वहाँ परिपत्र संदर्भ हैं वस्तुओं को साफ करने के लिए है, लेकिन कोई लाइव धागे अब और वस्तुओं के सभी संदर्भ पड़ता है। तो इस तरह एक परिपत्र संदर्भ होने से स्मृति रिसाव नहीं बनता है।

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