2008-11-05 15 views
54

मुझे पता है कि java.util में एक वीक हैशैप है, लेकिन चूंकि यह सब कुछ के लिए वीक रेफरेंस का उपयोग करता है, जिसे केवल इस मानचित्र द्वारा संदर्भित किया जाता है, संदर्भित ऑब्जेक्ट अगले जीसी चक्र पर खो जाएंगे। तो अगर आप यादृच्छिक डेटा कैश करना चाहते हैं तो यह लगभग बेकार है, जिसे शेष समय से हार्ड-लिंक किए बिना दोबारा अनुरोध किया जा सकता है। सबसे अच्छा समाधान एक नक्शा होगा, जो इसके बजाय सॉफ़्ट रेफरेंस का उपयोग करता है, लेकिन मुझे जावा आरटी पैकेज में कोई नहीं मिला।क्या जावा में सॉफ़्ट हैशैप है?

उत्तर

24

संपादित करें (अगस्त 2012):

ऐसा लगता है कि वर्तमान में सबसे अच्छा समाधान शायद अमरूद 13.0 के Cache वर्ग हैं, Guava's Wiki पर समझाया - कि मैं क्या उपयोग करने के लिए जा रहा हूँ है। यह SoftHashMap (CacheBuilder.newBuilder().softKeys() देखें) बनाने का भी समर्थन करता है, लेकिन शायद यह नहीं है कि आप क्या चाहते हैं, क्योंकि जावा विशेषज्ञ जेरेमी मैनसन बताते हैं (नीचे आपको लिंक मिलेगा)।


कि I know of (नवम्बर 2008), लेकिन आपको नेट पर SoftHashMap के कुछ कार्यान्वयन नहीं मिल रहा।

इस तरह की: SoftHashMap या this one


संपादित करें (नवंबर 2009)
Matthias के रूप में टिप्पणी में उल्लेख है, Google GuavaMapMaker उपयोग SoftReferences करता है:

एक ConcurrentMap बिल्डर, इन सुविधाओं के किसी भी संयोजन प्रदान:

  • मुलायम या कमजोर कुंजी,
  • मुलायम या कमजोर मूल्य,
  • समय समाप्ति, और
  • मूल्यों की मांग गणना पर।

this thread में उल्लेख किया है, एक और JSR166y उम्मीदवार:

jsr166y.ConcurrentReferenceHashMap

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


संपादित करें (अगस्त 2012)

Google कार्यान्वयन केवल पृष्ठभूमि थ्रेड का उपयोग करता है जब प्रविष्टियों की समयसीमा समाप्त होने का अनुरोध किया जाता है। विशेष रूप से, यह बस java.util.Timer का उपयोग करता है, जो एक अलग पृष्ठभूमि धागा होने के रूप में इतना घुसपैठ नहीं है।

जेरेमी मैनसन, की सिफारिश की गई किसी भी कैश के लिए, इस सुविधा का उपयोग SoftReference के खतरों से बचने के लिए: http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

वहाँ Apache Commons, अर्थात् org.apache.commons.collections.map.ReferenceMap से दूसरे कार्यान्वयन है; यह समय निकालने का समर्थन नहीं करता है, लेकिन यह चुनने का समर्थन करता है कि चाबियों की पहचान पहचान या समानता से की जानी चाहिए। इसके अलावा, यह कार्यान्वयन समवर्ती नहीं है - इसे सिंक्रनाइज़ किया जा सकता है, लेकिन यह कई धागे से पहुंच के तहत कम अच्छी तरह से काम करता है।

+0

एक अन्य उपयोगी कार्यान्वयन OpenJDK के अपने 'sun.security.util.Cache' है, जो एक अधिकतम आकार, समय-सीमित जीवनकाल, और SoftReferences बनाम सामान्य संदर्भ के एक विकल्प का समर्थन करता है है।जावा 7 में ऑब्जेक्ट्स ऑब्जेक्ट्स ऑब्जेक्ट्स में संस्करण; जावा 8 में संस्करण सामान्य है। जाहिर है, हमें सीधे 'सूर्य' सामान आयात नहीं करना चाहिए, लेकिन कोड जीपीएलएड है और यदि आप प्रारंभिक बिंदु चाहते हैं तो इसकी प्रतिलिपि बनाई जा सकती है। –

2
+1

मैं लगभग छह वर्षों तक एक परियोजना में सॉफ़्टहाश मैप के डॉ। कबाबज़ के मुद्दे 98 संस्करण का उपयोग कर रहा हूं और इस विशेष उपयोग के लिए यह अच्छी तरह से काम कर रहा है। यहां पेस्ट करने में थोड़ा लंबा लगता है, लेकिन आप jidesoft.swing.SoftHashMap और org.jvnet.substance.utils.SoftHashMap में एक उदाहरण पा सकते हैं। Org.pushingpixels.substance.internal.utils.SoftHashMap – jla

1

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

यदि कैश हटाने नीति महत्वपूर्ण है तो आपको नियमित संदर्भों का उपयोग करके अपनी खुद की संभावना पर ऐसा करने की आवश्यकता होगी। हालांकि आपको यह तय करना होगा कि वस्तुओं को बाहर निकालने के लिए कब और बाहर निकालना है। आप केवल बातें जब आप ढेर स्थान से बाहर चल रहे हैं कम करना चाहते हैं तो आप के माध्यम से उपलब्ध ढेर अंतरिक्ष क्वेरी कर सकते हैं:

Runtime.getRuntime().getFreeMemory(); 

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

यहां एक LRU cache है जिसे मैंने ओ (1) सम्मिलन, हटाने और लुकअप समय के साथ डिज़ाइन किया है, जिसमें कॉन्फ़िगर करने योग्य अधिकतम तत्व तत्व हैं। यदि आप कैश चाहते हैं तो यह सॉफ़्ट हैशैप की तुलना में बेहतर समाधान इमो है।

softreferences एक शानदार तरीका एक उगने वाली दाढ़ी कैश बनाने के लिए कर रहे हैं। तो आदर्श समाधान एक निश्चित निश्चित आकार कैश के साथ एक सॉफ्ट हैशैप का उपयोग करना होगा। कुछ संदर्भ के लिए दोनों तय कैश और नरम हैश मानचित्र में जाने तो कैश में सभी आवेषण है सिर्फ अगर देखना अपने नरम hashmap में (और कैश में संदर्भ समय अपडेट)। इस तरह से अपने सभी सबसे महत्वपूर्ण आइटम (अपनी चुनी नीति LRU, MFU, ... के अनुसार) को हटा दिया जाएगा कभी नहीं किया, क्योंकि वे कठिन कैश में संदर्भित हैं, लेकिन आप भी (कोई नीति पर नियंत्रण के साथ) और बातें पर पकड़ जाएगा, जब तक क्योंकि पर्याप्त स्मृति है।

+1

के रूप में एक tweaked संस्करण है जेरेमी Manson बताते हैं, समय हटाने (MapMaker से) सॉफ़्ट संदर्भों की समस्याओं का एक अच्छा समाधान है: http://jeremymanson.blogspot.de/ 2009/07/कैसे-हॉटस्पॉट-निर्णय लेता करने वाली clear_07.html अन्यथा, Apache Commons LRUMap के एक कार्यान्वयन, जोएल द्वारा नीचे उल्लेख बनाए रखता है। – Blaisorblade

20

मैं दो पुस्तकालयों की पेशकश है कि एक SoftHashMap कार्यान्वयन से परिचित हूँ:

  1. Apache Commons: org.apache.commons.collections.map.ReferenceMap

  2. Google Collections: com.google.common.collect .ReferenceMap

+3

संदर्भ संग्रह को Google संग्रह से हटा दिया गया है। अब MapMaker का प्रयोग करें। – Matthias

2

क्या आपने मुलायम हैश मैप के बजाय LRUMap का उपयोग करने पर विचार किया है? संग्रहीत होने पर आपको अधिक नियंत्रण मिलता है (या कम से कम, कितना)।

+0

एलआरयू वैध पुराने स्कूल दृष्टिकोण है। लेकिन एक नरम संदर्भ कैश को कैश और मेमोरी उपयोग में स्पाइक्स और घाटियों को अनुकूलित करने के लिए बेहतर काम करना चाहिए। शायद यही कारण है कि ओपी पहली जगह WeakReferenceMap के सॉफ़्ट रेफरेंस एनालॉग के लिए पूछ रहा था। – Javier

2

अपाचे Shiro कैशिंग के लिए बनाया गया एक SoftHashMap साथ आता है। यह उपरोक्त जेबी द्वारा पोस्ट किए गए आलेख पर आधारित है और अपाचे v2 के तहत लाइसेंस प्राप्त है। आप प्रलेखन here और स्रोत कोड here देख सकते हैं।