Java में SoftReference और WeakReference में क्या अंतर है?


810

बीच क्या अंतर है java.lang.ref.WeakReferenceऔर java.lang.ref.SoftReference?


9
SoftReferences प्रकार हैं (वास्तव में चर्चा के लिए नहीं) WeakReferences जो आमतौर पर तब एकत्रित होते हैं जब JVM को लगता है कि यह मेमोरी से बाहर है।
अजीत गंगा

5
@AjeetGanga, जब भी जीसी चलता है , लूज कमजोर रिफ हमेशा एकत्रित होते हैं । देखें stackoverflow.com/a/46291143/632951
पचेरियर

जवाबों:


926

एथेन निकोलस द्वारा कमजोर संदर्भों को समझने से :

कमजोर संदर्भ

एक कमजोर संदर्भ , सीधे शब्दों में कहें, एक संदर्भ है जो किसी वस्तु को स्मृति में रहने के लिए मजबूर करने के लिए पर्याप्त मजबूत नहीं है। कमजोर संदर्भ आपको कचरा संग्राहक की क्षमता का लाभ उठाने की अनुमति देते हैं, ताकि आपके लिए पुनराचल्यता निर्धारित की जा सके, इसलिए आपको इसे स्वयं करने की आवश्यकता नहीं है। आप इस तरह एक कमजोर संदर्भ बनाते हैं:

WeakReference weakWidget = new WeakReference(widget);

और फिर कोड में कहीं और आप weakWidget.get()वास्तविक Widgetवस्तु प्राप्त करने के लिए उपयोग कर सकते हैं । बेशक कमज़ोर संदर्भ कचरा संग्रहण को रोकने के लिए पर्याप्त मजबूत नहीं है, इसलिए आप पा सकते हैं (यदि विजेट के लिए कोई मजबूत संदर्भ नहीं हैं) जो कि weakWidget.get()वापस लौट रहे हैं null

...

नरम संदर्भ

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

SoftReferencesकी तुलना में किसी भी अलग तरह से व्यवहार करने की आवश्यकता नहीं है WeakReferences, लेकिन व्यवहार में कोमलता से उपलब्ध वस्तुओं को आम तौर पर बनाए रखा जाता है जब तक कि स्मृति भरपूर मात्रा में होती है। यह उन्हें कैश के लिए एक उत्कृष्ट आधार बनाता है, जैसे कि ऊपर वर्णित छवि कैश, क्योंकि आप कचरा संग्रहकर्ता को दोनों के बारे में चिंता करने दे सकते हैं कि ऑब्जेक्ट कैसे पहुंच योग्य हैं (एक जोरदार पहुंच योग्य वस्तु कैश से कभी नहीं निकाली जाएगी) और कितनी बुरी तरह से स्मृति वे उपभोग कर रहे हैं की जरूरत है।

और पीटर केसलर ने एक टिप्पणी में जोड़ा:

सन JRE सॉफ्टरेफर को अलग तरह से कमजोर करता है। यदि उपलब्ध स्मृति पर दबाव नहीं है, तो हम एक सॉफ्टरफेर द्वारा संदर्भित ऑब्जेक्ट पर पकड़ बनाने का प्रयास करते हैं। एक विवरण: "-client" और "-server" JRE के लिए नीति अलग हैं: -client JRE ढेर का विस्तार करने के बजाय SoftReferences को साफ़ करने के लिए अपने पदचिह्न को छोटा रखने की कोशिश करता है, जबकि -server JRE आपके रखने की कोशिश करता है उच्च प्रदर्शन को वरीयता देकर (यदि संभव हो तो) स्पष्ट सॉफ्टराइफ़र्स के बजाय उच्च प्रदर्शन करना। एक साइज सबके लिए फ़िट नहीं होता है।


7
कोई और अधिक उपलब्ध पोस्ट नहीं, आप इसे वेनबैक मशीन पर देख सकते हैं: web.archive.org/web/20061130103858/http://weblogs.java.net/blog/…
riccardo.tasso

इस बार, संग्रह अब उपलब्ध नहीं है
user1506104

209

कमजोर संदर्भों को उत्सुकता से एकत्र किया जाता है। यदि GC को पता चलता है कि कोई वस्तु कमजोर रूप से उपलब्ध है (केवल कमजोर संदर्भों के माध्यम से पहुंच योग्य), तो यह उस वस्तु के कमजोर संदर्भों को तुरंत साफ कर देगा। जैसे, वे एक वस्तु का संदर्भ रखने के लिए अच्छे हैं, जिसके लिए आपका कार्यक्रम भी (दृढ़ता से संदर्भित) "संबंधित जानकारी" रखता है, जैसे किसी वर्ग के बारे में कैश्ड प्रतिबिंब की जानकारी, या किसी वस्तु के लिए एक आवरण, आदि। ऑब्जेक्ट के साथ जुड़े रहने के बाद कोई अर्थ नहीं है GC-ed। जब कमजोर संदर्भ साफ हो जाता है, तो यह एक संदर्भ कतार में संलग्न हो जाता है कि आपका कोड कहीं और मतदान करता है, और यह संबंधित वस्तुओं को भी हटा देता है। अर्थात्, आप किसी वस्तु के बारे में अतिरिक्त जानकारी रखते हैं, लेकिन उस वस्तु को एक बार देखने के लिए संदर्भित करने की आवश्यकता नहीं होती है। वास्तव में, कुछ स्थितियों में आप WeakReference को भी हटा सकते हैं और WeakReference उप-वर्ग के क्षेत्रों में ऑब्जेक्ट के बारे में संबंधित अतिरिक्त जानकारी रख सकते हैं। WeakReference का एक और विशिष्ट उपयोग विहित उदाहरणों को रखने के लिए मैप्स के साथ संयोजन में है।

दूसरी ओर SoftReferences बाहरी, मनोरंजक संसाधनों को कैच करने के लिए अच्छे हैं क्योंकि जीसी आमतौर पर उन्हें साफ़ करने में देरी करते हैं। हालांकि यह गारंटी दी जाती है कि OutOfMemoryError को फेंकने से पहले सभी SoftReferences साफ हो जाएंगे, इसलिए वे सैद्धांतिक रूप से OOME [*] पैदा नहीं कर सकते।

विशिष्ट उपयोग के मामले का उदाहरण एक फ़ाइल से सामग्री का एक संक्षिप्त रूप रख रहा है। आप एक ऐसी प्रणाली लागू करेंगे, जहाँ आप किसी फ़ाइल को लोड करेंगे, उसे पार्स करेंगे, और पार्स किए गए प्रतिनिधित्व के मूल ऑब्जेक्ट के लिए एक सॉफ्टरेंस को रखेंगे। अगली बार जब आपको फ़ाइल की आवश्यकता होगी, तो आप इसे SoftReference द्वारा पुनः प्राप्त करने का प्रयास करेंगे। यदि आप इसे पुनः प्राप्त कर सकते हैं, तो आप अपने आप को एक और लोड / पार्स को बख्शते हैं, और यदि जीसी ने इस बीच इसे मंजूरी दे दी है, तो आप इसे लोड करते हैं। इस तरह, आप प्रदर्शन अनुकूलन के लिए मुफ्त मेमोरी का उपयोग करते हैं, लेकिन किसी OOME को जोखिम में नहीं डालते हैं।

अब [*] के लिए। SoftReference रखना अपने आप में एक OOME कारण नहीं बन सकता है। यदि दूसरी ओर आप गलती से किसी कार्य के लिए SoftReference का उपयोग करते हैं तो WeakReference का उपयोग करने के लिए होता है (अर्थात, आप किसी वस्तु से जुड़ी जानकारी को किसी भी तरह से दृढ़तापूर्वक संदर्भित करते हैं, और जब संदर्भ ऑब्जेक्ट साफ़ हो जाता है, तो उसे छोड़ दें), आप OOME के ​​रूप में चला सकते हैं आपका कोड जो ReferenceQueue को प्रदूषित करता है और संबंधित वस्तुओं को डिस्क्राइब करता है, वह समय पर नहीं चल सकता है।

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


14
कमजोर वस्तुओं का उपयोग कब किया जाएगा, इसके स्पष्टीकरण के लिए विशेष रूप से उपयोगी है।
जैक बेनिम्बल

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

मैं यह समझने के लिए संघर्ष कर रहा हूं कि अगर यह हमेशा महत्वपूर्ण कुंजी ऑब्जेक्ट के लिए कमजोर संदर्भ उत्पन्न करता है तो WeakHashMap का उपयोग क्या है?

@ सुपरकैट, जीसी रनों का निरीक्षण करने के लिए केवल एक उचित उपयोग है WeakReference। विस्तार देखें: stackoverflow.com/a/46291143/632951
पेसियर

1
@ स्पेसर: उस पोस्ट का लेखक केवल गलत है। वह कुछ अन्य उपयोग परिदृश्यों की उपेक्षा करता है जैसे घटना सदस्यता, उनका दूसरा बिंदु निरर्थक है, और उनका तीसरा बिंदु मानता है कि एक प्रोग्रामर उन चीजों को कर सकता है जो संभव नहीं हो सकता है। उनकी पहली बात वाजिब है, लेकिन मैंने जो कहा, उससे सीधे जुड़ाव। यदि कोड को अक्सर बड़ी अपरिवर्तनीय वस्तुओं का निर्माण और तुलना करनी होगी , उदाहरण के लिए, भवन का हिस्सा अक्सर सस्ता होगा यदि कोड नई वस्तुओं का निर्माण करता है, भले ही वे पहले से मौजूद हों, लेकिन एक वस्तु और खुद के बीच तुलना (समान संदर्भ) होगी ...
सुपरकाट

155

जावा में ; सबसे मजबूत से सबसे कमजोर तक के आदेश हैं: मजबूत, नरम, कमजोर और प्रेत

एक मजबूत संदर्भ एक सामान्य संदर्भ है जो संदर्भित ऑब्जेक्ट को GC द्वारा संग्रह से बचाता है। यानी कभी कचरा इकट्ठा नहीं होता।

एक नरम संदर्भ कचरा संग्रहकर्ता द्वारा संग्रह के लिए योग्य है, लेकिन संभवतः तब तक एकत्र नहीं किया जाएगा जब तक कि इसकी स्मृति की आवश्यकता न हो। पहले कचरा इकट्ठा होता है OutOfMemoryError

एक कमजोर संदर्भ एक संदर्भ है जो जीसी द्वारा संग्रह से एक संदर्भित वस्तु की रक्षा नहीं करता है। जब कोई स्ट्रॉन्ग या सॉफ्ट रिफल्स नहीं आता है तो कचरा इकट्ठा होता है।

एक प्रेत संदर्भ एक वस्तु का संदर्भ है जिसे अंतिम रूप दिए जाने के बाद प्रेत संदर्भित किया जाता है, लेकिन इससे पहले कि इसकी आवंटित स्मृति को पुनः प्राप्त किया गया हो।

स्रोत

सादृश्य: मान लें कि एक जेवीएम एक राज्य है, वस्तु राज्य का एक राजा है, और जीसी राज्य का एक हमलावर है जो राजा (वस्तु) को मारने की कोशिश करता है।

  • जब किंग स्ट्रॉन्ग होता है , तो GC उसे मार नहीं सकता है।
  • जब राजा शीतल होता है , तो GC उस पर हमला करता है, लेकिन राजा जब तक संसाधन उपलब्ध नहीं होते, तब तक वह राज्य पर शासन करता है।
  • जब राजा कमजोर होता है , तो जीसी उस पर हमला करता है, लेकिन सुरक्षा के बिना राज्य पर शासन करता है।
  • जब राजा प्रेत है , तो जीसी ने उसे पहले ही मार दिया था लेकिन राजा उसकी आत्मा के माध्यम से उपलब्ध है।

7
नरम संदर्भ ... until memory is availableइसका कोई मतलब नहीं है। क्या आपका मतलब है is eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use?
टूलमेकरवेट

1
हाँ, कचरा संग्रहकर्ता तब तक संदर्भ एकत्र नहीं करेगा जब तक कि मेमोरी उपलब्ध न हो।
प्रेमराज Prem

2
मुझे सरल समझाया गया सामान पसंद है, मेरे से बहुत अधिक ब्ला ब्ला ब्ला 1 के बिना!
एडेलिन

3
अभिनव उदाहरण के साथ उत्कृष्ट सारांश
रविन्द्र बाबू

+1, आगे पढ़ रहे हैं: javarevisited.blogspot.in/2014/03/…
roottraveller

77

कमजोर संदर्भ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

सिद्धांत: weak reference कचरा संग्रहण से संबंधित है। आम तौर पर, एक या अधिक होने वाली वस्तु referenceकचरा संग्रहण के लिए पात्र नहीं होगी।
उपरोक्त सिद्धांत लागू नहीं है जब यह है weak reference। यदि किसी वस्तु में अन्य वस्तुओं के साथ केवल कमजोर संदर्भ है, तो कचरा संग्रह के लिए तैयार है।

आइए नीचे दिए गए उदाहरण को देखें: हमारे पास Mapउन वस्तुओं के साथ है जहां कुंजी एक वस्तु है।

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

अब, कार्यक्रम के निष्पादन के दौरान हमने बनाया है emp = nullMapपकड़े कुंजी के रूप में यह है कोई मतलब नहीं यहाँ बनाता है null। उपरोक्त स्थिति में, वस्तु कचरा एकत्र नहीं है।

WeakHashMap

WeakHashMapवह जगह है जहाँ प्रविष्टियाँ ( key-to-value mappings) को हटा दिया जाएगा जब उन्हें पुनः प्राप्त करना संभव नहीं होगा Map

मुझे WeakHashMap के साथ उपरोक्त उदाहरण दिखाते हैं

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

आउटपुट:20 calls to System.gc() परिणाम में लिया गया aMap size: 0।

WeakHashMapचाबियों के केवल कमजोर संदर्भ हैं, अन्य Mapवर्गों की तरह मजबूत संदर्भ नहीं । ऐसी स्थितियाँ हैं जिनका आपको ध्यान रखना पड़ता है जब आपने उपयोग किया है तब मूल्य या कुंजी को दृढ़ता से संदर्भित किया जाता है WeakHashMap। यह एक WeakReference में ऑब्जेक्ट को लपेटकर बचा जा सकता है ।

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

शीतल संदर्भ।

Soft Referenceथोड़ा मजबूत है कि कमजोर संदर्भ। नरम संदर्भ कचरा संग्रहण की अनुमति देता है, लेकिन कचरा संग्रहकर्ता से यह साफ करने के लिए कहा जाता है कि कोई अन्य विकल्प नहीं है।

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


5
तुम एक मिल सकता है NullPointerExceptionमें aMap.get().put(...)
xehpuk

आपका पहला HashMap उदाहरण गलत दिखता है। जब आप "aMap.put (एम्प, वैल);" 'एम्प' और 'वैल' दोनों ही मजबूत संदर्भ हैं। आंतरिक रूप से, 'एम्प' और 'वैल' धारण करने के लिए एक नया वैरिएबल बनाया जाता है, इसलिए जब आप "एम्प = नल" करते हैं; आप सिर्फ "एम्प" वेरिएबल को ही सीमित कर रहे हैं, लेकिन आंतरिक रूप से हैश मैप को वेरिएबल नहीं है (जो अभी भी मूल कर्मचारी वस्तु को पकड़े हुए है)। इसलिए हैश मैप 'एम्प' का एक मजबूत संदर्भ रखेगा, भले ही आप 'एम्प' वेरिएबल के बाहर क्या करें।
टिआगो

@Tiago। संभवतः "प्रथम उदाहरण" द्वारा आप उदाहरण का उल्लेख कर रहे हैं WeakHashMap(क्योंकि यह पहला ऐसा है जो कमजोर व्यवहार प्रदर्शित कर रहा है)। "WeakHashMap" के लिए डॉक्टर को देखें: WeakHashMap "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. " का उपयोग करने का पूरा बिंदु यह है कि आपको WeakReference में घोषणा / पास-इन नहीं करनी है; WeakHashMap आंतरिक रूप से आपके लिए ऐसा करता है। docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
ToolmakerSteve

0 पर कॉल किया। System.gc () के परिणाम को कमजोर करने के लिए इसका आकार देखें: 0 आपके दूसरे प्रोग्राम का आउटपुट है?
एडलिन

1
WeakHashMapएक्शन के एक अन्य उदाहरण के लिए , उदाहरण के साथ ऐप दिखा रहा है कि कैसे कचरा-संग्रह निष्पादित होने के बाद ही प्रविष्टियाँ हटा दी जाती हैं , मेरे प्रश्न का उत्तर देखें , क्या WeakHashMap कभी-बढ़ रहा है, या यह कचरा कुंजियों को साफ करता है?
बेसिल बोर्क

50

नरम संदर्भ और कमजोर संदर्भ के बीच एकमात्र वास्तविक अंतर यही है

कचरा संग्रहकर्ता यह तय करने के लिए एल्गोरिदम का उपयोग करता है कि क्या एक नरम रूप से पहुंच योग्य वस्तु को पुनः प्राप्त करना है या नहीं, लेकिन हमेशा कमजोर रूप से पुनः प्राप्त वस्तु को पुनः प्राप्त करता है।


@ तत्र, समीर। मैंने इस उत्तर पर यहां विस्तार किया: stackoverflow.com/a/46291143/632951
पेसियर

25

SoftReferenceकैश के लिए डिज़ाइन किया गया है। जब यह पाया जाता है कि एक WeakReferenceसंदर्भ अन्यथा अप्राप्य वस्तु है, तो यह तुरंत साफ हो जाएगा। SoftReferenceके रूप में छोड़ा जा सकता है। आम तौर पर मुफ्त मेमोरी की मात्रा से संबंधित कुछ एल्गोरिथ्म होता है और अंतिम समय यह निर्धारित करने के लिए उपयोग किया जाता है कि क्या इसे साफ़ किया जाना चाहिए। वर्तमान सन एल्गोरिथ्म संदर्भ को साफ करने के लिए है अगर इसका उपयोग कई सेकंड में नहीं किया गया है क्योंकि जावा हीप पर मेमोरी फ्री (मेगावर्टेबल, सर्वर हॉटस्पॉट चेक द्वारा निर्धारित अधिकतम संभव हीप -Xmx) के खिलाफ मेगाबाइट मुफ्त हैं । SoftReferenceएस को OutOfMemoryErrorफेंके जाने से पहले साफ कर दिया जाएगा, जब तक कि अन्यथा उपलब्ध न हो।


9
लेकिन एंड्रॉइड में इसे caches developer.android.com/reference/java/lang/ref/… के
यारोस्लाव Mytkalyk

4
@DoctororDrive tbf सवाल जावा के बारे में था, न कि सात्विक! :-P
फेबस्प्रो

2
@YaroslavMytkalyk, फ्रैंकली, अगर एंड्रॉइड एक वर्ग के व्यवहार को फिर से लिखना चाहता है, तो उसे अपने स्वयं के नामस्थान का उपयोग करना चाहिए, न कि java.lang। पर्यायवाची शब्द का ऐसा दुरुपयोग कोई भी अच्छा नहीं कर रहा है।
पेसियर

9

यह लेख मजबूत, नरम, कमजोर और प्रेत संदर्भों को समझने के लिए सुपर सहायक हो सकता है।


आपको एक सारांश देने के लिए,

यदि आपके पास केवल किसी ऑब्जेक्ट के कमजोर संदर्भ हैं (कोई मजबूत संदर्भ नहीं है), तो ऑब्जेक्ट को अगले जीसी चक्र में जीसी द्वारा पुनः प्राप्त किया जाएगा।

यदि आपके पास केवल किसी ऑब्जेक्ट के लिए नरम संदर्भ हैं (कोई मजबूत संदर्भ नहीं है), तो वह ऑब्जेक्ट केवल GC द्वारा पुनः प्राप्त किया जाएगा जब JVM मेमोरी से बाहर निकलता है।


तो आप कह सकते हैं कि, मजबूत संदर्भों में अंतिम शक्ति होती है (जीसी द्वारा कभी एकत्र नहीं की जा सकती)

नरम संदर्भ कमजोर संदर्भों की तुलना में शक्तिशाली होते हैं (चूंकि वे जीसी चक्र से बच सकते हैं जब तक कि जेवीएम मेमोरी से बाहर नहीं निकलता)

कमजोर संदर्भ नरम संदर्भों की तुलना में भी कम शक्तिशाली होते हैं (क्योंकि वे किसी भी जीसी चक्र को प्रवाहित नहीं कर सकते हैं और यदि कोई अन्य मजबूत संदर्भ नहीं है तो उन्हें पुनः प्राप्त किया जाएगा)।


भोजनालय सादृश्य

  • वेटर - जीसी
  • आप - ढेर में वस्तु
  • रेस्टॉरेंट एरिया / स्पेस - हीप स्पेस
  • नया ग्राहक - नई वस्तु जो रेस्तरां में टेबल चाहती है

अब यदि आप एक मजबूत ग्राहक (मजबूत संदर्भ के अनुरूप) हैं, तो भी अगर कोई नया ग्राहक रेस्तरां में आता है या ऐसा कभी खुश हो जाता है, तो आप अपनी मेज (ढेर पर स्मृति क्षेत्र) को कभी नहीं छोड़ेंगे। वेटर को आपको (या यहां तक ​​कि आपसे) रेस्तरां छोड़ने का अनुरोध करने का कोई अधिकार नहीं है।

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

यदि आप एक कमजोर ग्राहक (कमजोर संदर्भ के अनुरूप) हैं, तो वेटर, उसकी इच्छा पर, (किसी भी समय) आपको रेस्तरां छोड़ने के लिए कह सकता है: P


7

केवल वास्तविक अंतर

प्रति डॉक , ढीले WeakReferences चाहिए एक चल रहा है जी सी द्वारा हटाए जा।

प्रति डॉक , ढीले SoftReferences चाहिए OOM से पहले साफ हो फेंक दिया है।

बस यही असली अंतर है। बाकी सब कुछ अनुबंध का हिस्सा नहीं है। (मुझे लगता है कि नवीनतम डॉक्स संविदात्मक हैं।)

SoftReferences उपयोगी हैं। मेमोरी-संवेदी कैश्स सॉफ्टरफेर का उपयोग करते हैं, न कि वीकेरिफायर का।


WeakReference का एकमात्र उचित उपयोग GC रन का निरीक्षण करना है। आप एक नया WeakReference बनाकर ऐसा करते हैं, जिसका ऑब्जेक्ट तुरंत दायरे से बाहर चला जाता है, फिर शून्य से बाहर निकलने की कोशिश करें weak_ref.get()। जब यह होता है null, तो आप सीखते हैं कि इस अवधि के बीच, जीसी भाग गया।

WeakReference के गलत उपयोग के लिए , सूची अंतहीन है:

  • प्राथमिकता -२ मृदुता को लागू करने के लिए एक घटिया हैक, जैसे कि आपको एक लिखना नहीं है, फिर भी यह अपेक्षित रूप से काम नहीं करता है क्योंकि हर जीसी रन पर कैश साफ़ हो जाएगा , भले ही स्पेयर मेमोरी हो। चरणों के लिए https://stackoverflow.com/a/3243242/632951 देखें । (इसके अलावा, अगर आपको कैश प्राथमिकता के 2 से अधिक स्तरों की आवश्यकता है, तो आपको अभी भी इसके लिए एक वास्तविक पुस्तकालय की आवश्यकता होगी।)

  • एक मौजूदा वर्ग की वस्तु के साथ डेटा को जोड़ने के लिए एक घटिया हैक, फिर भी यह एक मेमोरी लीक (OutOfMemoryError) बनाता है जब आपका जीसी आपके कमजोरियों के बनने के बाद ब्रेक लेने का फैसला करता है। इसके अलावा, यह बदसूरत से परे है: ट्यूपल्स का उपयोग करने के लिए एक बेहतर तरीका है।

  • किसी मौजूदा वर्ग के ऑब्जेक्ट के साथ डेटा को जोड़ने के लिए एक घटिया हैक, जहां क्लास में खुद को नॉन-सबक्लेसेबल बनाने के लिए तंत्रिका है, और मौजूदा फ़ंक्शन कोड में उपयोग किया जाता है जिसे आपको कॉल करने की आवश्यकता है। ऐसे मामले में, उचित समाधान यह है कि या तो कक्षा को संपादित करें और इसे उप-योगीय बनाएं, या फ़ंक्शन को संपादित करें और इसे क्लास के बजाय एक इंटरफ़ेस बनाएं, या वैकल्पिक फ़ंक्शन का उपयोग करें।


कैश के बारे में क्या है जहां कुंजी का प्रकार equals()सिर्फ वस्तु पहचान है? शीतल संदर्भ वहाँ एक बर्बादी की तरह लग रहे हैं, क्योंकि एक बार एक महत्वपूर्ण वस्तु अब दृढ़ता से उपलब्ध नहीं है, कोई भी कभी भी उस मैपिंग को फिर से नहीं देखेगा।
HighCommander4

मैं असहमत हूं। जब भी आप GC को प्रभावित नहीं करना चाहते तो WeakReference का उपयोग करें (आप किसी ऑब्जेक्ट संदर्भ को सहेजना चाहते हैं और बाद में जांच कर सकते हैं कि क्या यह अभी भी मौजूद है, बिना किसी वरीयता के जो यह करता है)। यदि आप वस्तु को रखने और रखने के लिए GC को प्रभावित करना चाहते हैं, तो SoftReference का उपयोग करें (यानी जब आप पसंद करेंगे कि GC इसे रखेगा)।
डेविड रेफेली

एक अच्छा उदाहरण जहां WeakReference का उपयोग करना है वह Android के AsyncTask में है - संदर्भ का एक उदाहरण रखने के लिए। इस तरह यदि संदर्भ मर जाता है (यदि गतिविधि - स्क्रीन रोटेशन, आदि), तो AsyncTask के पास इसका कोई मजबूत संदर्भ नहीं होगा, और इसलिए यह कचरा एकत्र किया जा सकता है। Youtu.be/…
डेविड रेफेल

3

जावा में छह प्रकार के ऑब्जेक्ट रीचबिलिटी स्टेट्स:

  1. मजबूत लाइक पहुंच योग्य वस्तुएं - जीसी इस तरह की वस्तु को इकट्ठा नहीं करेगा ( द्वारा कब्जा की गई मेमोरी को पुनः प्राप्त करें )। ये एक रूट नोड या किसी अन्य दृढ़ता से पहुंच योग्य वस्तु (जैसे स्थानीय चर, वर्ग चर, उदाहरण चर, आदि) के माध्यम से उपलब्ध हैं।
  2. सॉफ्ट लाइक रीचेबल ऑब्जेक्ट्स - GC मेमोरी कंटेस्टेंट के आधार पर इस तरह के ऑब्जेक्ट को इकट्ठा करने का प्रयास कर सकता है । ये एक या अधिक सॉफ्ट रेफरेंस ऑब्जेक्ट के माध्यम से रूट से पहुंच योग्य हैं
  3. कमजोर गीत पुन: प्राप्य वस्तुएं - जीसी को इस तरह की वस्तु को इकट्ठा करना होगा । ये एक या अधिक कमजोर संदर्भ वस्तुओं के माध्यम से रूट से उपलब्ध हैं
  4. पुनर्जीवित-सक्षम वस्तुएं - जीसी पहले से ही इन वस्तुओं को इकट्ठा करने की प्रक्रिया में है। लेकिन वे कुछ फाइनलरों के निष्पादन से मजबूत राज्यों / मजबूत / नरम / कमजोर हो सकते हैं
  5. फैंटम लाइक रीचेबल ऑब्जेक्ट - जीसी पहले से ही इन ऑब्जेक्ट्स को इकट्ठा करने की प्रक्रिया में है और किसी भी फाइनलर द्वारा इसे पुनर्जीवित करने में सक्षम नहीं होने का निर्धारण किया गया है (यदि यह खुद को अंतिम रूप देता है) (तब इसका फाइनल रन हो गया होगा) । ये एक या अधिक प्रेत संदर्भ वस्तुओं के माध्यम से रूट से उपलब्ध हैं
  6. अगम्य वस्तु - एक वस्तु न तो दृढ़ता से, न कोमलता से, न कमजोरता से, न ही प्रेत के कारण, और पुनरुत्थान योग्य नहीं है। ये वस्तुएं पुनः प्राप्ति के लिए तैयार हैं

अधिक जानकारी के लिए: https://www.artima.com/insidejvm/ed2/gc16.html «ढहना


4
प्रेत संदर्भों का अच्छा वर्णन नहीं। इसके अलावा, आप 4 प्रकार के अजीबोगरीब क्रम में सूचीबद्ध हैं। "प्रेत" सबसे कमजोर प्रकार है, सबसे मजबूत प्रकार नहीं। इन्हें सूचीबद्ध करने का पारंपरिक क्रम "मजबूत, नरम, कमजोर, प्रेत" है। और मुझे नहीं पता कि आपको यह धारणा कहां से मिली कि प्रेत यंत्रों का उपयोग कैशिंग तंत्र के लिए किया जाता है। AFAIK, वे एक अस्थायी राज्य हैं जिसे केवल GC द्वारा देखा जाता है, ऐसा कुछ नहीं जो एक साधारण प्रोग्रामर के साथ काम करेगा।
टूलमेकरसैट

@ToolmakerSteve और सभी - कुछ बातों के लिए क्षमा याचना 1. मेरे उत्तर के पिछले संस्करण में प्रेत संदर्भों की गलत व्याख्या, और 2. त्रुटियों को सुधारने में देरी। अब त्रुटियों को ठीक करके उत्तर में सुधार किया गया है
वि.वि.सागरसागर

1

किसी को पता होना चाहिए कि एक कमजोर संदर्भित ऑब्जेक्ट केवल तभी एकत्र किया जाएगा जब उसके पास केवल कमजोर संदर्भ (एस) हों। यदि इसका इतना मजबूत संदर्भ है, तो यह एकत्र नहीं होता है कि इसके पास कितने कमजोर संदर्भ हैं।


यह सामान्य ज्ञान है ... एक ही सॉफ्टएयर और फैंटम के लिए जाता है।
3

1

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

भारी भार के तहत हीप और जीसी व्यवहार

  • मजबूत / हार्ड संदर्भ - जैसा कि कार्यक्रम जारी रहा, JVM बरकरार रखी गई संदर्भित ऑब्जेक्ट को एकत्रित नहीं कर सका। अंततः "java.lang.OutOfMemoryError: Java हीप स्पेस" समाप्त हुआ
  • शीतल संदर्भ - जैसे-जैसे कार्यक्रम जारी रहा, ढेर का उपयोग बढ़ता रहा, लेकिन OLD जीन GC हुआ, यह अधिकतम ढेर के पास था। कार्यक्रम शुरू करने के बाद समय में जीसी थोड़ा बाद में शुरू हुआ।
  • कमजोर संदर्भ - जैसे ही कार्यक्रम शुरू हुआ, वस्तुओं ने अंतिम रूप देना शुरू कर दिया और लगभग तुरंत एकत्रित हो गए। ज्यादातर वस्तुओं को युवा पीढ़ी के कचरा संग्रह में एकत्र किया गया।
  • प्रेत संदर्भ - कमजोर संदर्भ के समान, प्रेत संदर्भित वस्तुओं को भी अंतिम रूप दिया जाना शुरू हो गया है और कचरा तुरंत एकत्र हो गया है। कोई पुरानी पीढ़ी जीसी नहीं थी और सभी वस्तुओं को युवा पीढ़ी के कचरा संग्रह में ही एकत्र किया जा रहा था।

आप इस प्रयोग के लिए गहराई से रेखांकन, आँकड़े, अवलोकन प्राप्त कर सकते हैं


0

WeakReference : (लघु या पूर्ण) वस्तुओं है कि केवल कमजोर संदर्भित हर जीसी चक्र पर एकत्र कर रहे हैं।

SoftReference : जब वे वस्तुएँ जो केवल कोमलता से संदर्भित होती हैं, एकत्र की जाती हैं, इस पर निर्भर करती हैं:

  1. -XX: SoftRefLRUPolicyMSPerMB = N ध्वज (डिफ़ॉल्ट मान 1000 है, उर्फ ​​1 सेकंड)

  2. ढेर में मुफ्त मेमोरी की मात्रा।

    उदाहरण:

    • ढेर में 10 एमबी मुक्त स्थान (पूर्ण जीसी के बाद) है;
    • -XX: SoftRefLRUPolicyMSPerMB = 1000

    तब ऑब्जेक्ट जो केवल SoftReference द्वारा संदर्भित किया जाता है, अगर पिछली बार जब इसे एक्सेस किया जाता है तो इसे 10 सेकंड से अधिक एकत्र किया जाएगा।

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