2009-03-13 13 views
40

यदि मेरे एप्लिकेशन में बहुत से स्थिर चर या विधियां हैं, तो परिभाषा के अनुसार वे ढेर में संग्रहीत किए जाएंगे। अगर मैं गलत हूं तो कृपया मुझे सही करेंजावा में मेमोरी रिसाव के कारण बहुत से स्थिर चर का उपयोग कर सकते हैं?

1) क्या ये चर लागू होने तक ढेर पर होंगे?
2) क्या वे किसी भी समय जीसी के लिए उपलब्ध होंगे? यदि नहीं, तो क्या मैं कह सकता हूं कि यह एक स्मृति रिसाव है?

उत्तर

76

स्टेटिक विधियां केवल विधियां हैं, वे ढेर पर संग्रहीत नहीं हैं, वे सिर्फ "यह" पैरामीटर का उपयोग नहीं करते हैं।

स्टेटिक चर जीसी के लिए "जड़ों" के रूप में कार्य करते हैं। नतीजतन, जब तक कि आप उन्हें स्पष्ट रूप से शून्य पर सेट नहीं करते हैं, तब तक वे तब तक जीवित रहेंगे जब तक कार्यक्रम रहता है, और इसलिए सबकुछ उनसे पहुंच योग्य है।

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

ढेर के बारे में आपके प्रश्न के लिए: जावा में सभी ऑब्जेक्ट्स या तो ढेर या ढेर पर मौजूद हैं। ऑब्जेक्ट नए ऑपरेटर के साथ ढेर पर बनाए जाते हैं। उसके बाद एक संदर्भ संलग्न किया जाता है। यदि संदर्भ शून्य हो जाता है या दायरे से बाहर हो जाता है (उदाहरण के लिए, ब्लॉक का अंत), जीसी को पता चलता है कि उस वस्तु तक पहुंचने का कोई तरीका नहीं है और इसे पुनः प्राप्त किया गया है। यदि आपका संदर्भ स्थैतिक चर में है, तो यह कभी भी गुंजाइश से बाहर नहीं होता है लेकिन आप इसे अभी भी शून्य या किसी अन्य ऑब्जेक्ट पर सेट कर सकते हैं।

+0

आईआईआरसी स्थिर क्षेत्रों को जीसीड किया जाएगा, जैसे ही उन्हें घोषित किया गया वर्ग जीसीड है।यदि वर्ग का वां elast उदाहरण चला गया है तो कक्षा घोषणा की जाएगी और इसके साथ स्थिर क्षेत्र होंगे। – ordnungswidrig

+1

मुझे यकीन नहीं है कि @ o11rig पूरी तरह से सटीक है, लेकिन मेरा मानना ​​है कि जीसी को कक्षाओं के लिए सांख्यिकी एकत्र करने की अनुमति है जिनके पास कुछ परिस्थितियों में कोई सदस्य नहीं है। मैंने इसे दो स्रोतों से सुना है, लेकिन कभी भी सटीक स्पष्टीकरण नहीं सुना है। –

+0

थोड़ा क्विबल: सभी जावा * ऑब्जेक्ट्स * ढेर में रहते हैं। ऑब्जेक्ट * रेफरेंस * और प्राइमेटिव्स को स्टैक पर संग्रहीत किया जा सकता है यदि वे वर्तमान में निष्पादन विधि के स्थानीय हैं, और अन्यथा ढेर पर संग्रहीत हैं। (जेआईटी के साथ किसी भी आधुनिक जेवीएम में छोड़कर, जहां जेआईटी का ऑप्टिमाइज़र ऑब्जेक्ट्स को जहां भी पसंद करता है, तब तक रख सकता है, जब तक कि यह अभी भी * कार्य करता है * ऑब्जेक्ट्स जैसे ही ढेर पर होता है।) और यह तर्क दिया जा सकता है कि स्थैतिक तरीकों - या , कम से कम, जावा बाइटकोड जो उन्हें लागू करता है - कक्षा ऑब्जेक्ट के हिस्से के रूप में ढेर पर भी रहता है जो कक्षा को दर्शाता है जहां उन्हें परिभाषित किया गया था। –

1

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

क्या आप इसे मेमोरी रिसाव कह सकते हैं, मैं इसे मेमोरी लीक नहीं कहूंगा, आम तौर पर एक मेमोरी लीक मेमोरी होती है जिसे आप सामान्य रूप से पुनर्प्राप्त करने की उम्मीद करते हैं लेकिन आप कभी नहीं करते हैं, या आप केवल इसका हिस्सा पुनर्प्राप्त करते हैं। इसके अलावा स्मृति रिसाव आमतौर पर समय में भी बदतर हो जाते हैं (उदाहरण: हर बार जब आप एक विधि को कॉल करते हैं तो अधिक स्मृति "लीक" होती है) हालांकि इस मामले में उन चर के लिए स्मृति उपयोग स्थिर (प्रकार) स्थिर है।

+0

आपके कोड से संदर्भित स्थिर चर के लिए कोई आवश्यकता नहीं है ... क्लास लोडर स्थायी रूप से एक संदर्भ रखता है और इसलिए जीसी कभी नहीं लाएगा। – ReneS

1

यह क्लासिक सी अर्थ में एक स्मृति रिसाव का कारण नहीं बनेगा ... उदाहरण

Class A{ 

static B foo; 

... 

static void makeFoo(){ 
    foo = new B(); 
    foo = new B(); 
} 

के लिए इस मामले में, makeFoo() के लिए एक कॉल के रूप में एक स्मृति रिसाव का कारण नहीं बनेगा, पहला उदाहरण कचरा इकट्ठा किया जा सकता है।

2

स्थैतिक द्वारा संदर्भित सीधे या अप्रत्यक्ष रूप से ऑब्जेक्ट्स उचित वर्ग लोडर एकत्र किए जाने तक ढेर पर बने रहेंगे। ऐसे मामले हैं (उदाहरण के लिए थ्रेडलोकल) जहां अन्य ऑब्जेक्ट्स अप्रत्यक्ष रूप से क्लास लोडर को संदर्भित करते हैं जिससे यह अचयनित रहता है।

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

3

यदि आपके पास स्थिर हैशैप है और आप इसमें डेटा जोड़ते हैं ... डेटा कभी गायब नहीं होगा और आपके पास रिसाव होगी - अगर आपको डेटा की आवश्यकता नहीं है। यदि आपको डेटा की आवश्यकता है, तो यह रिसाव नहीं है, लेकिन स्मृति के एक विशाल ढेर के आसपास लटक रहा है।

+0

मान लें कि स्थिर हैशप में बहुत सारी वस्तुएं हैं; और मैंने नक्शा का संदर्भ शून्य में बनाया है (इसमें सभी ऑब्जेक्ट्स नहीं हैं)? क्या यह एक स्मृति रिसाव है? चूंकि आपने कहा है कि "वर्ग लोडर स्थायी रूप से एक स्थिर संदर्भ रखता है और इसलिए जीसी कभी किक नहीं करेगा"? –

+0

यदि आप स्थिर संदर्भ को शून्य पर सेट करते हैं और आपने उस मानचित्र को कहीं और संदर्भित नहीं किया है, तो स्मृति मुक्त हो जाएगी। उस मैप किए गए संदर्भित वस्तुओं को भी मुक्त किया जाएगा यदि उन्हें किसी और द्वारा संदर्भित नहीं किया जाता है। – ReneS

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