2009-05-12 10 views
95

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

जावा में, null करने के लिए वस्तु के संदर्भ की स्थापना करता है प्रदर्शन या कचरा संग्रहण क्षमता में सुधार? यदि हां, तो यह किस मामले में एक मुद्दा है? कंटेनर कक्षाएं? ऑब्जेक्ट संरचना? बेनामी आंतरिक कक्षाएं?

मैं इसे कोड में अक्सर देखता हूं। क्या यह अब अप्रचलित प्रोग्रामिंग सलाह है या यह अभी भी उपयोगी है?

+2

पढ़ सकते हैं यह प्रोफाइल। आधुनिक रनटाइम पर आपको प्रदर्शन या मेमोरी पदचिह्न में कोई सार्थक वृद्धि नहीं दिखाई देनी चाहिए। –

+12

@ जेसन, प्रोफाइल? यह मानता है कि मैं इसका जवाब देने के लिए पर्याप्त पर्याप्त परिणाम सेट करने के लिए मामलों के एक बड़े सेट को प्रोफाइल कर दूंगा। और यह कि मैं मामलों का एक सेट नहीं चुनता कि वीएम को जीसी और प्रदर्शन मुद्दों को मुखौटा करने के लिए पर्याप्त अनुकूलित किया गया है। यही कारण है कि मैं इसे यहाँ पूछ रहा हूँ। उन मामलों की भावना प्राप्त करने के लिए जहां यह एक मुद्दा है। – sal

+1

http://stackoverflow.com/questions/449409/does-assigning-objects-to-null-in-java-impact-garbage-collection का डुप्लिकेट। –

उत्तर

65

यह है जब आप संदर्भ nulling की सोच रहे थे पर थोड़ा निर्भर करता है।

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

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

मामले में जहां वहाँ होने की कुछ सलाह एक लंबे दायरे जहां मेमोरी-गहन वस्तु गुंजाइश के माध्यम से बीच-बीच में इस्तेमाल किया जा रह गए में अशक्त के लिए संदर्भ सेट करने के लिए विशेष रूप से किया गया था इस्तेमाल किया। उदाहरण के लिए:

{ 
    BigObject obj = ... 
    doSomethingWith(obj); 
    obj = null;    <-- explicitly set to null 
    doSomethingElse(); 
} 

तर्क है कि यहाँ क्योंकि obj दायरे में अब भी है, तो संदर्भ की स्पष्ट nulling बिना, यह नहीं कचरा संग्रहणीय जब तक के बाद doSomethingElse() विधि को पूरा करता हो जाता है था। और यह सलाह है कि शायद आधुनिक JVMs पर नहीं रखता है: यह पता चला है कि जेआईटी कंपाइलर उस बिंदु पर काम कर सकता है जब किसी दिए गए स्थानीय ऑब्जेक्ट संदर्भ का उपयोग नहीं किया जाता है।

+1

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

+0

मुझे शायद यह जोड़ना चाहिए: ऊपर दी गई सलाह आम तौर पर पालन करने वाली सलाह है, अच्छी तरह से व्यवहार की गई पुस्तकालयों, एक अच्छी तरह से व्यवहार किए गए वीएम इत्यादि को मानना। यदि आपको लगता है कि आपके पास एक थ्रेड पूल लाइब्रेरी है जो ऑब्जेक्ट्स पर लटकती है नौकरी खत्म होने के बाद, अच्छी तरह से ... यह थ्रेड पूल लाइब्रेरी में एक बग है जिसे शायद ऑब्जेक्ट संदर्भ को नलाने के द्वारा काम किया जा सकता है, लेकिन कम छोटी गाड़ी थ्रेड पूल लाइब्रेरी का उपयोग करके आसपास भी काम किया जा सकता है। मुझे यकीन नहीं है कि इस तरह की एक बग सामान्य डिजाइन सिद्धांतों को बदलती है। –

24

नहीं, यह अप्रचलित सलाह नहीं है। उलझन में संदर्भ अभी भी एक समस्या है, विशेष रूप से यदि आप एक पूर्व-आवंटित सरणी का उपयोग कर विस्तारणीय सरणी कंटेनर (ArrayList या जैसा) लागू कर रहे हैं, तो कहें। सूची के "तार्किक" आकार से परे तत्वों को हटा दिया जाना चाहिए, अन्यथा वे मुक्त नहीं होंगे।

देखें प्रभावी जावा 2 एड, आइटम 6: अप्रचलित ऑब्जेक्ट संदर्भ हटा दें।

+0

क्या यह एक भाषा मुद्दा है या एक वीएम कार्यान्वयन मुद्दा है? –

+4

यह एक "अर्थपूर्ण" मुद्दा है। असल में, क्योंकि आपने एक सरणी को प्रीलोकेट किया है, वीएम इसे देखता है।यह आपके कंटेनर के "तार्किक" आकार के बारे में कुछ भी नहीं जानता है। मान लें कि आपके पास 16-तत्व सरणी द्वारा समर्थित आकार 10 का ऐरेलिस्ट है। वीएम नहीं जानता कि आइटम 10..15 वास्तव में उपयोग नहीं किया जाता है; अगर उन स्लॉट में सामग्री है, तो उन्हें मुक्त नहीं किया जाएगा। –

+0

कंटेनर कक्षाओं के बाहर के बारे में क्या? ऑब्जेक्ट संरचना में जहां आंतरिक ऑब्जेक्ट बाहरी ऑब्जेक्ट द्वारा आवंटित नहीं किया जाता है। – sal

4

स्मृति प्रतिबंधात्मक वातावरण (जैसे सेलफोन) में यह उपयोगी हो सकता है। शून्य सेट करके, objetc को gc'd होने के दायरे से बाहर निकलने के लिए चर का इंतजार करने की आवश्यकता नहीं है।

रोजमर्रा की प्रोग्रामिंग के लिए, तथापि, यह नहीं नियम होना चाहिए, विशेष मामलों को छोड़कर की तरह एक क्रिस जेस्टर-यंग का हवाला दिया।

9

उदाहरण के मैदान, सरणी तत्वों

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

पैथोलॉजिकल मामले वह ऑब्जेक्ट है जो पूरे एक्सएमएल डोम पेड़ को एक अनैतिक उदाहरण बनाए रखता है जिसे इसे कॉन्फ़िगर करने के लिए उपयोग किया गया था, एमबीन जो अनियंत्रित नहीं था, या एक बेरोजगार वेब एप्लिकेशन से किसी ऑब्जेक्ट का एकल संदर्भ जो पूरी तरह से रोकता है Unloaded होने से classloader।

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

scoped चर:

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

{ 
    BigObject obj = ... 
    doSomethingWith(obj); 
    obj = null;   // <-- explicitly set to null 
    doSomethingElse(); 
} 

हो जाता है

{ 
    { 
    BigObject obj = ... 
    doSomethingWith(obj); 
    } //   <-- obj goes out of scope 
    doSomethingElse(); 
} 

लांग, फ्लैट स्कोप, आम तौर पर कोड की स्पष्टता के लिए बुरा कर रहे हैं भी। केवल उस उद्देश्य के लिए चीजों को तोड़ने के लिए निजी तरीकों का परिचय देना भी अनसुना नहीं है।

+0

यदि आप एक मजबूत संदर्भ का जिक्र कर रहे हैं, तो यह सच है, लेकिन सभी संदर्भों के लिए नहीं। जावा में कमजोर संदर्भ कचरा एकत्र किया जा सकता है। –

0

सबसे पहले, यह कुछ भी है कि आप अशक्त करने के लिए एक वस्तु की स्थापना कर रहे हैं मतलब यह नहीं है। मैं नीचे समझा:

List list1=new ArrayList(); 
List list2=list1; 

ऊपर कोड खंड हम क्या कर रहे है, असल में हम ArrayList वस्तु की वस्तु संदर्भ चर नाम List1 कि स्मृति में संग्रहीत किया जाता है बना रहे हैं। तो सूची 1 उस वस्तु का जिक्र कर रही है और यह एक चर से अधिक नोटिंग है। और कोड की दूसरी पंक्ति में हम List2 में List1 के संदर्भ कॉपी कर रहे हैं। तो अब वापस अपने प्रश्न के लिए जा रहा है, तो मुझे क्या करना:

list1=null; 

List1 इसका मतलब है कि स्मृति में संग्रहीत किया जाता है ताकि List2 भी उल्लेख करने के लिए कुछ भी नहीं होने होगा किसी भी वस्तु जिक्र नहीं रह गया है। तो अगर आप List2 के आकार की जाँच करें:

list2.size(); //it gives you 0 

तो यहाँ कचरा कलेक्टर की अवधारणा आता है जो कहते हैं "आप स्मृति है कि वस्तु से पकड़ मुक्त कराने के बारे में चिंता की बात नहीं है, मैं क्या करेंगे कि जब मैं पाते हैं कि यह अब प्रोग्राम में उपयोग नहीं करेगा और जेवीएम मुझे प्रबंधित करेगा। "

मुझे आशा है कि यह अवधारणा साफ़ करें।

0

कारणों ऐसा करने के लिए में से एक अप्रचलित वस्तु संदर्भ खत्म करने के लिए है। आप पाठ here.

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