2012-02-06 12 views
7

जावाडॉक्स कहते हैं, "जब एक कुंजी को उसकी प्रविष्टि को त्याग दिया गया है तो प्रभावी ढंग से मानचित्र से हटा दिया गया है"।WeakHashMap और दृढ़ता से संदर्भित मान

लेकिन जब तक कोई अन्य धागा नहीं होता है जो कभी-कभी Map.Entry प्रविष्टियों को हटा देता है, तो क्या मूल्य वस्तुओं को मानचित्र द्वारा दृढ़ता से संदर्भित नहीं किया जाएगा? लेकिन चूंकि ऐसा कोई धागा चल रहा है, केवल get विधि आमंत्रण ऐसी प्रविष्टियों को हटा सकता है - एक समय में।

मैं उस कारण से लगभग हमेशा WeakHashMap<K, WeakReference<V>> का उपयोग करता हूं। वे डिफ़ॉल्ट व्यवहार क्यों नहीं कर पाएंगे - कमजोर संदर्भों के रूप में मूल्य भी?

+0

http://stackoverflow.com/questions/2473410/question-about-weakhashmap लगभग एक प्रश्न है। लेकिन मैं जानना चाहता था कि मेरा दावा सही है या नहीं: एक प्रविष्टि केवल तभी हटा दी जाएगी जब() पता चलता है कि कुंजी जीसीएड की गई है, जो स्पष्ट रूप से बहुत मूल्यवान प्रतीत नहीं होता है जब तक कि मैं कमजोरियों को मूल्यों के रूप में उपयोग नहीं करता। –

+0

हाँ, यह अभी मतदान किया गया है। यदि आप कुछ अलग करना चाहते हैं, तो अपना खुद का संस्करण लिखें। –

+2

यदि आपको कुछ अलग चाहिए, तो लाइब्रेरी का उपयोग करें - अपना खुद का लेखन बहुत मुश्किल है। गुवा के पास 'मैपमेकर' है, जो आपको कुंजी और मूल्य संदर्भों की ताकत को कॉन्फ़िगर करने देता है: http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapMaker। एचटीएमएल –

उत्तर

8

संदर्भ पंक्तियों को स्वचालित रूप से प्रविष्टियों को निकालने के लिए उपयोग किया जाता है।

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/ReferenceQueue.html

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

मूल रूप से, कमजोर संदर्भ कचरा कलेक्टर का एक प्रमुख हिस्सा हैं, इसलिए जब एक जीसी झाडू होता है, अप्रयुक्त संदर्भ पाए जाते हैं और कतारों पर रखा और फिर कार्रवाई उन कतारों की सामग्री के आधार पर लिया जा सकता है।

एक थ्रेड कतार की remove विधि पर साफ-सफाई करने की आवश्यकता होने पर चेतावनी दी जा सकती है या poll कतार।

"Java theory and practice: Plugging memory leaks with weak references" बताते हैं:

WeakHashMap के कार्यान्वयन को दिखाता है कमजोर संदर्भों के साथ एक आम मुहावरा - कि कुछ आंतरिक वस्तु WeakReference फैली हुई है।

...

WeakHashMap नक्शा कुंजी पकड़े, जो कुंजी वस्तुओं कचरा एकत्र होने के लिए जब वे अब आवेदन के द्वारा उपयोग किया जाता है की अनुमति देता है के लिए कमजोर संदर्भ का उपयोग करता है, और get() कार्यान्वयन एक से एक जीवित मानचित्रण बता सकते हैं WeakReference.get()null पर मृत व्यक्ति द्वारा मृत। लेकिन यह मैप की स्मृति खपत को पूरे जीवन भर में बढ़ने से बचाने के लिए आवश्यक है; मुख्य ऑब्जेक्ट एकत्र किए जाने के बाद मानचित्र से मृत प्रविष्टियों को छूने के लिए कुछ भी किया जाना चाहिए। अन्यथा, मानचित्र बस मृत कुंजी से संबंधित प्रविष्टियों को भर देगा। और जब यह एप्लिकेशन के लिए अदृश्य होगा, तब भी यह एप्लिकेशन को स्मृति से बाहर निकलने का कारण बन सकता है क्योंकि Map.Entry और value ऑब्जेक्ट्स एकत्र नहीं किए जाएंगे, भले ही कुंजी हो।

...

संदर्भ कतारों कचरा कलेक्टर की वस्तु जीवन चक्र के बारे में आवेदन करने के लिए जानकारी वापस खिला के प्राथमिक साधन हैं। कमजोर संदर्भों में दो रचनाकार हैं: कोई केवल तर्क के रूप में संदर्भ को लेता है और दूसरा संदर्भ संदर्भ भी लेता है। जब एक संदर्भ संदर्भ कतार के साथ एक कमजोर संदर्भ बनाया गया है और संदर्भ जीसी के लिए एक उम्मीदवार बन जाता है, संदर्भ संदर्भ के बाद संदर्भ वस्तु (संदर्भ नहीं) संदर्भ कतार पर लगाया जाता है।एप्लिकेशन फिर संदर्भ कतार से संदर्भ पुनर्प्राप्त कर सकता है और सीख सकता है कि संदर्भ को एकत्रित किया गया है ताकि यह संबंधित सफाई गतिविधियों को निष्पादित कर सके, जैसे कमजोर संग्रह से निकलने वाली वस्तुओं के लिए प्रविष्टियों को समाप्त करना। (संदर्भ कतारों BlockingQueue रूप में एक ही dequeuing मोड उपलब्ध होते हैं - सर्वेक्षण में शामिल, समय समाप्त हो गया अवरुद्ध, और untimed अवरुद्ध।)

संपादित करें:

भी कतारों के साथ, कमजोर नक्शे अभी भी लीक कर सकते हैं। Ephemerons उस मामले को हल करने का प्रयास है जहां एक कमजोर कुंजी एक दृढ़ता से आयोजित मूल्य का संदर्भ देता है जो कुंजी का संदर्भ देता है। वे जावा में लागू नहीं हैं।

एफेमरन एक ऐसी समस्या का समाधान करते हैं जो आमतौर पर रजिस्ट्री का उपयोग करके वस्तुओं को "संलग्न" करने का प्रयास करते समय मिलता है। जब किसी संपत्ति को किसी वस्तु से जोड़ा जाना चाहिए, तो संपत्ति को (जीसी व्यवहार के संदर्भ में) आमतौर पर जीवन-समय होता है कि इस वस्तु का एक उदाहरण चर होगा।

property --------- registry --------- association --------- object 

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

एफेमरन इस समस्या को हल करके इस समस्या को हल करते हैं कि एक इफेमरॉन की 'सामग्री' (मान) दृढ़ता से तब तक आयोजित की जाएगी जब तक कुंजी को कचरा इकट्ठा नहीं किया जाता है। तब से, इफेमरन की सामग्री कमजोर हो जाएगी। इसलिए, एक इफेमरन की सामग्री कचरा संग्रह के लिए योग्य हो सकती है यदि केवल और यदि कुंजी कचरा इकट्ठा करने योग्य हो, जो सटीक व्यवहार है जिसे हम ऑब्जेक्ट के आवृत्ति चर के लिए देखेंगे।

+0

संदर्भ कतार की अपनी हुक को कॉल करने की क्षमता के बारे में भूल गए। –

+0

मुझे आपके लिंक से मिला "WeakHashMap में एक निजी विधि है जिसे expungeStaleEntries() कहा जाता है जिसे अधिकांश मानचित्र संचालन के दौरान बुलाया जाता है।" उपयोगी होना। और आश्चर्य कीजिए कि क्या एक थ्रेड फैलाना जो संदर्भ कतार पर वास्तव में अवरुद्ध करता है, एक बेहतर विचार हो सकता है। हो सकता है कि अमरूद के MapMaker क्या करता है। –

+1

@UstamanSangat, मुझे नहीं पता कि MapMaker क्या करता है, लेकिन हो सकता है कि expungeStaleEntries() मानचित्र के उपयोग के साथ सफाई को amortize करने के लिए संदर्भ कतार चुनाव। मैं अपनी खुद की कुंजी सफाई को लागू करने के साथ चारों ओर घूमने से पहले मैपमेकर जैसे कुछ का उपयोग करने की कोशिश करता हूं।बीटीडब्ल्यू, मैंने एक संपादन जोड़ा जो कमजोर कुंजी मानचित्रों का उपयोग करके भी स्मृति को रिसाव कर सकता है। –