जावा के संदर्भ वर्गों को समझना: सॉफ्टरफरेंस, कमजोर संदर्भ और फैंटम संदर्भ


81

क्या कोई तीन संदर्भ वर्गों (या एक अच्छी व्याख्या के लिए एक लिंक पोस्ट) के बीच अंतर समझा सकता है? SoftReference> WeakReference> PhantomReference, लेकिन जब मैं हर एक का प्रयोग करेंगे? क्यों है WeakHashMapलेकिन एक नहीं SoftHashMapया नहीं PhantomHashMap?

और अगर मैं निम्नलिखित कोड का उपयोग करता हूं ...

WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) {                 // ref can get collected at any time...
    System.gc();                   // Let's assume ref gets collected here.
    System.out.println(ref.get()); // Now what?!
}

...क्या होता है? क्या मुझे जांचना होगा refकि क्या प्रत्येक कथन से पहले अशक्त है (यह गलत है, लेकिन मुझे क्या करना चाहिए )? तेजी से आग के सवालों के लिए खेद है, लेकिन मुझे इन Referenceकक्षाओं को समझने में परेशानी हो रही है ... धन्यवाद!


1
क्यों, WeakHashMapलेकिन कोई SoftHashMapया नहीं PhantomHashMapउत्कृष्ट सवाल है, मैंने पहले इस पर ध्यान क्यों नहीं दिया .. ??
मेहराज मलिक

1
ref != nullजांच कोई मतलब नहीं है। refकभी नहीं होगा null
होल्गर

क्यू में जोड़ना strongRef --> weakRef --> objA:। अब, objAGCed किया जाएगा या नहीं, क्योंकि यह एक अप्रत्यक्ष रेफरी है strongRef
समशर्स

जवाबों:


60

पैकेज के लिएjava.lang.ref जावा लाइब्रेरी प्रलेखन तीन स्पष्ट संदर्भ प्रकारों की घटती ताकत की विशेषता है।

SoftReferenceजब आप संदर्भित ऑब्जेक्ट को जीवित रहने के लिए चाहते हैं, तब तक आप इसका उपयोग करते हैं, जब तक कि होस्ट प्रक्रिया स्मृति पर कम चल रही हो। जब तक कलेक्टर को मेमोरी को खाली करने की आवश्यकता नहीं होती तब तक वस्तु संग्रह के योग्य नहीं होगी । ढीले ढंग से कहा गया है, एक SoftReferenceसाधन बांधने , "जब तक आप अब और नहीं कर सकते तब तक वस्तु को पिन करें।"

इसके विपरीत, WeakReferenceजब आप संदर्भित ऑब्जेक्ट के जीवनकाल को प्रभावित नहीं करना चाहते हैं , तब उपयोग करें ; आप केवल संदर्भित ऑब्जेक्ट के बारे में एक अलग दावा करना चाहते हैं , इसलिए जब तक यह जीवित रहता है। संग्रह के लिए ऑब्जेक्ट की पात्रता बाध्य WeakReferenceएस की उपस्थिति से प्रभावित नहीं होती है । वस्तु उदाहरण से संबंधित संपत्ति के लिए बाहरी मानचित्रण की तरह कुछ, जहां संपत्ति को केवल तब तक दर्ज करने की आवश्यकता होती है जब तक संबंधित वस्तु जीवित है, WeakReferenceएस और के लिए एक अच्छा उपयोग है WeakHashMap

पिछले एक PhantomReference- मुश्किल चरित्र के लिए। जैसे WeakReference, इस तरह की बाध्यता PhantomReferenceसंदर्भित वस्तु के जीवनकाल पर कोई प्रभाव नहीं डालती है। लेकिन अन्य संदर्भ प्रकारों के विपरीत, कोई भी किसी को भी नहीं दे सकता है PhantomReference। एक मायने में, यह उस चीज़ की ओर इशारा नहीं करता है जो इसे इंगित करता है, जहां तक ​​कॉलर बता सकते हैं। यह केवल संदर्भित वस्तु के साथ कुछ संबंधित डेटा को संबद्ध करने की अनुमति देता है- डेटा जिसे बाद में निरीक्षण किया जा सकता है और उस पर कार्रवाई की जा सकती है जब PhantomReferenceइसके संबंधित में कतारबद्ध हो ReferenceQueue। आम तौर पर एक से एक प्रकार प्राप्त होता है PhantomReferenceऔर उस व्युत्पन्न प्रकार में कुछ अतिरिक्त डेटा शामिल होते हैं। दुर्भाग्य से, इस तरह के व्युत्पन्न प्रकार का उपयोग करने के लिए कुछ डाउनकास्टिंग शामिल है।

आपके उदाहरण कोड में, यह refसंदर्भ नहीं है (या, यदि आप पसंद करते हैं, तो "चर") जो शून्य हो सकता है। बल्कि, यह कॉलिंग द्वारा प्राप्त मूल्य है Reference#get()जो शून्य हो सकता है। यदि यह अशक्त पाया जाता है, तो आपको बहुत देर हो चुकी है; संदर्भित वस्तु पहले से ही एकत्रित होने के रास्ते पर है:

final String val = ref.get();
if (null != val)
{
  // "val" is now pinned strongly.
}
else
{
  // "val" is already ready to be collected.
}

क्यू में जोड़ना strongRef --> weakRef --> objA:। अब, objAGCed किया जाएगा या नहीं, क्योंकि यह एक अप्रत्यक्ष रेफरी है strongRef
समशर्स

अगर मैं आपके प्रश्न को सही ढंग से समझता हूं, @samshers, objAकचरा के रूप में संग्रह के लिए योग्य है। किसी WeakReferenceवस्तु पर उस वस्तु पर कोई प्रभाव न डालते हुए एक बाहरी वस्तु को पिन करना WeakReference
सेह

श्रृंखला में एक मजबूत संदर्भ नहीं होने से फर्क पड़ता है। क्योंकि objAकचरा इकट्ठा होने के लिए कमजोर संदर्भ को पहले सही हटा दिया जाना चाहिए। और एक मजबूत संदर्भ कमजोर संदर्भ की ओर इशारा कर रहा है जो कमजोर रेफरी को GCed होने के लिए अयोग्य
बनाता है

नहीं, WeakReferenceएकत्र किए जाने की अनुमति देने के objAलिए एकत्र होने की आवश्यकता नहीं है । WeakReferenceनहीं रखता है objAजिंदा। इसके बजाय, यह एक तरीका है, objAजबकि यह जीवित है - उस जीवनकाल को प्रभावित किए बिना - और पता लगाता है कि कलेक्टर ने पहले ही इसे दूर कर लिया।
seh

6

एक लिंक: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

PhantomHashMapgetहमेशा बहुत अच्छी तरह से काम नहीं करेगा हमेशा nullप्रेत के संदर्भ के लिए रिटर्न ।

कैश मुश्किल है, इसलिए SoftHashMapजितना आप सोच सकते हैं उतना काम नहीं करेगा। हालाँकि, मेरा मानना ​​है कि Google के संग्रह पुस्तकालय में एक सामान्य संदर्भ मानचित्र कार्यान्वयन है।

आपको हमेशा जांच करनी चाहिए कि getरिटर्न नॉन- null। (ध्यान दें, Referenceयह जाँचना नहीं है कि संदर्भ स्वयं नहीं है- null) नजरबंद स्ट्रिंग्स के मामले में यह हमेशा रहेगा, लेकिन (हमेशा की तरह) इसके बारे में "चतुर" होने की कोशिश न करें।


लिंक की समय सीमा समाप्त हो गई है।
महराज मलिक

@MehrajMalik लिंक तय
टॉम हॉन्टिन -

क्यू में जोड़ना strongRef --> weakRef --> objA:। अब, objAGCed किया जाएगा या नहीं, क्योंकि यह एक अप्रत्यक्ष रेफरी है strongRef
s

3

यह भी उल्लेख किया जाना चाहिए, जैसा कि ट्रूंग जुआन तिन्ह द्वारा टिप्पणी पर कहा गया है, यहां: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/

यह JRockit JVM Sun JVM की तुलना में कमजोर / नरम / प्रेत संदर्भों को अलग-अलग लागू करता है।


0
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;

if (ref != null) {                 
    System.gc(); 
    System.out.println(ref.get());
}

इस मामले में, यह अशक्त उत्पादन करेगा। यहां कॉल System.gc()महत्वपूर्ण है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.