2012-10-15 17 views
9

मैं ऐसे एप्लिकेशन पर काम कर रहा हूं जिसमें बहुत सारे डुप्लिकेट स्ट्रिंग हैं और मेरा काम स्मृति उपयोग को कम करने के लिए उन्हें खत्म करना है। मेरा पहला विचार यह सुनिश्चित करने के लिए String.intern का उपयोग करना था कि स्ट्रिंग का केवल एक संदर्भ मौजूद होगा। यह ढेर मेमोरी को कम करने के लिए काम करता था, लेकिन यह परमजेन के रास्ते में बहुत अधिक वृद्धि हुई; वास्तव में, क्योंकि कई तार हैं जिन्हें केवल एक बार घोषित किया जाता है, वास्तव में आवेदन द्वारा उपयोग की जाने वाली स्मृति की कुल मात्रा में वृद्धि हुई है।स्मृति उपयोग को बढ़ाने के बिना हमेशा स्ट्रिंग के समान संदर्भ का उपयोग करने के लिए कोड को मैं कैसे अनुकूलित कर सकता हूं?

अन्य विचारों की खोज करने के बाद, मुझे यह दृष्टिकोण मिला: https://stackoverflow.com/a/725822/1384913

यह स्ट्रिंग.intern जैसा ही हुआ: स्ट्रिंग उपयोग में कमी आई, लेकिन मैंने जो स्मृति सहेजी है, उसका उपयोग WeakHashMap और WeakHashMap$Entry कक्षाओं में किया जा रहा है।

क्या प्रत्येक स्ट्रिंग के लिए केवल एक संदर्भ बनाए रखने का एक प्रभावी तरीका है जो उसी स्मृति की मात्रा नहीं व्यतीत करता है जिसे मैं ठीक कर रहा हूं?

+2

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

+3

आप एक ऐसे प्रश्न को देख सकते हैं जो मैंने एक समान प्रश्न को दिया है http://stackoverflow.com/a/12793823/57695 –

+0

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

उत्तर

1

मुझे WeakHashMap का विकल्प मिला: WeakHashSet एक्लिप्स जेडीटी लाइब्रेरी द्वारा प्रदान किया गया। यह वही व्यवहार है जो WeakHashMap है, लेकिन यह कम स्मृति का उपयोग करता है। साथ ही, आपको केवल add विधि को कॉल करने की आवश्यकता है और यह सेट में स्ट्रिंग को जोड़ देगा यदि यह अभी तक मौजूद नहीं है, या मौजूदा को वापस लौटा रहा है।

एकमात्र चीज जो मुझे पसंद नहीं थी वह यह तथ्य था कि यह जेनरिक का उपयोग नहीं करता है, जिससे डेवलपर को वस्तुओं को कास्ट करने के लिए मजबूर किया जाता है। मेरे intern विधि निकला बहुत सरल हो सकता है, जैसा कि आप bellow देख सकते हैं: WeakHashSet की

घोषणा:

private static WeakHashSet stringPool = new WeakHashSet(30000); //30 thousand is the average number of Strings that the application keeps. 

और प्रशिक्षु विधि:

public static String intern(String value) { 
    if(value == null) { 
     return null; 
    } 
    return (String) stringPool.add(value); 
} 
0

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

0

इसी तरह, जहां भी संभव हो, मैंने स्ट्रिंग स्थिरांक को enums पर दोहराया। इस तरह, आप दो लाभ मिलेंगे:

  • enum उदाहरणों एकमात्र हैं, इसलिए आप जब तार का उपयोग कर स्मृति समस्याओं
  • टाइप की कोई गलती नहीं होगी।

विपक्ष:

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