2010-05-11 6 views
36

follwing HashMap.clear() कोड पर विचार करें:जावा हैश मैप.क्लियर() और हटाएं() मेमोरी प्रभावी है?

/** 
* Removes all of the mappings from this map. 
* The map will be empty after this call returns. 
*/ 
public void clear() { 
    modCount++; 
    Entry[] tab = table; 
    for (int i = 0; i < tab.length; i++) 
     tab[i] = null; 
    size = 0; 
} 

ऐसा लगता है, कि Entry वस्तुओं की आंतरिक सरणी (table) shrinked कभी नहीं किया गया है। इसलिए, जब मैं मानचित्र में 10000 तत्व जोड़ता हूं, और उसके बाद map.clear() पर कॉल करता है, तो यह 10000 नल को इसके आंतरिक सरणी में रखेगा। तो, मेरा सवाल यह है कि, JVM इस सरणी को कैसे संभालता है, और इस प्रकार, HashMap मेमोरी प्रभावी है?

+5

10,000 नल सभी 40 केबी (संभवतः 64 बिट जेवीएम पर 80) लेते हैं। –

+8

@ माइकल, शायद, लेकिन यह अप्रासंगिक है: संख्या को किसी भी पैमाने पर विस्तारित किया जा सकता है। ओपी सिद्धांत के मामले पर पूछ रहा है। शायद नक्शा बड़ा है, शायद उपलब्ध स्मृति छोटी है। हमें पता नहीं। – corsiKa

+2

मानचित्र में 10000 तत्व! = आंतरिक तालिका में 10000 प्रविष्टियां। कृपया जानें कि हैश मैप इत्यादि पहले कैसे काम करता है ... – james

उत्तर

57

विचार यह है कि clear() केवल तभी कॉल किया जाता है जब आप HashMap का पुन: उपयोग करना चाहते हैं। ऑब्जेक्ट का पुन: उपयोग करना केवल उसी कारण से किया जाना चाहिए जिसका उपयोग पहले किया गया था, इसलिए संभावना है कि आपके पास लगभग समान प्रविष्टियां होंगी। Map के बेकार सिकुड़ने और आकार बदलने से बचने के लिए क्षमता clear() कहलाती है।

सब आप क्या करना चाहते Map में डेटा को छोड़, तो आप की जरूरत नहीं है (और वास्तव में नहीं होना चाहिए) उस पर clear() कहते हैं, लेकिन बस स्पष्ट Map खुद के सभी संदर्भ है, जो मामले में यह हो जाएगा है अंततः कचरा इकट्ठा किया।

+0

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

+1

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

+5

@ शमन: आपने जो कुछ भी दिया है वह सिंगलटन पैटर्न का उपयोग न करने का एक अन्य कारण है ;-) –

4

आप सही हैं, लेकिन यह मानते हुए कि सरणी बढ़ाना एक बहुत महंगा ऑपरेशन है, हैशैप के लिए यह अनुचित नहीं है कि "उपयोगकर्ता ने सरणी में वृद्धि करने के बाद, संभावना है कि उसे बाद में इस आकार को सरणी की आवश्यकता होगी "और इसे कम करने के बजाय सरणी छोड़ दें और बाद में इसे विस्तार से विस्तारित करने का जोखिम उठाएं। यह एक उदारवादी है मुझे लगता है - आप भी दूसरी तरफ वकालत कर सकते हैं।

4

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

हालांकि, अगर आपको Map द्वारा उपयोग की जाने वाली स्मृति को भी मुक्त करने की आवश्यकता है, तो आपको इसे Joachim सॉर के सुझाव के अनुसार जारी करना चाहिए।

9

Looking at the source code, यह HashMap जैसा कभी नहीं दिखता है। जब भी आवश्यक हो, resize विधि को आकार को दोगुना करने के लिए कहा जाता है, लेकिन इसमें कुछ भी नहीं है ArrayList.trimToSize()

आप इस तरह से कि यह बढ़ता है और नाटकीय रूप से अक्सर सिकुड़ता में एक HashMap उपयोग कर रहे हैं, तो आप सिर्फ बजाय clear() बुला की एक नई HashMap बनाना चाह सकते हैं।

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