.Net में कमजोर संदर्भों का उपयोग कब करें?


56

मैं व्यक्तिगत रूप से ऐसी स्थिति में नहीं आया हूं जहां मुझे WeakReference प्रकार का .Net में उपयोग करने की आवश्यकता है, लेकिन लोकप्रिय धारणा यह है कि यह कैश में उपयोग किया जाना चाहिए। डॉ जॉन हारॉप अपने में कैश में WeakReferences के इस्तेमाल के खिलाफ एक बहुत अच्छा मामले दिया जवाब के लिए इस सवाल।

मैंने अक्सर AS3 डेवलपर्स को मेमोरी फ़ुटप्रिंट पर बचाने के लिए कमजोर संदर्भों का उपयोग करने के बारे में बात करते हुए सुना है, लेकिन मैंने जो बातचीत की है, उसके आधार पर यह आवश्यक लक्ष्य को पूरा किए बिना जटिलता को जोड़ने के लिए लगता है, और रनटाइम व्यवहार बल्कि अप्रत्याशित है। इतना तो है कि बहुत से लोग इसे छोड़ देते हैं और इसके बजाय स्मृति उपयोग को अधिक सावधानी से प्रबंधित करते हैं / अपने कोड को कम मेमोरी इंटेंसिव (या अधिक सीपीयू-साइकिल और छोटे मेमोरी फुटप्रिंट के व्यापार-बंद बनाने) का अनुकूलन करते हैं।

डॉ। जॉन हैरोप ने भी अपने जवाब में बताया कि .Net कमजोर संदर्भ नरम नहीं हैं, और gen0 पर कमजोर संदर्भों का एक आक्रामक संग्रह है। MSDN के अनुसार , लंबे कमजोर संदर्भ आपको एक वस्तु को फिर से बनाने की क्षमता प्रदान करते हैं but the state of the object remains unpredictable.,!

इन विशेषताओं को देखते हुए, मैं ऐसी स्थिति के बारे में नहीं सोच सकता जहां कमजोर संदर्भ उपयोगी होंगे, शायद कोई मुझे बता सके?


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

2
@ itsme86 - मैं बुलेट-प्रूफ उपयोग के मामले की तलाश में नहीं हूं, बस यह कि कमजोर संदर्भ एक अच्छा फिट हैं और समझ में आता है। उदाहरण के लिए कैश का उपयोग मामला, क्योंकि कमजोर संदर्भों को इतनी उत्सुकता से एकत्र किया जाता है कि यह अधिक कैश मिस होने का कारण बनता है, तब भी जब आपके पास बहुत सारी मेमोरी उपलब्ध हो

4
मैं थोड़ा निराश हूं कि इसे बंद करने के लिए कई वोट मिल रहे हैं। मैं इस बारे में कोई जवाब या कुछ चर्चा देखकर बुरा नहीं मानूंगा (b4 में "स्टैक ओवरफ्लो एक मंच नहीं है")।
ta.speot.is

@theburningmonk स्मृति लाभ के बदले में ऑफसेट है। आज के ढांचे में, यह संदेह है कि कोई भी कैश को लागू करने के दौरान सीधे वीकेरिजन टूल के लिए पहुंच जाएगा, क्योंकि व्यापक कैशिंग सिस्टम आसानी से उपलब्ध हैं।

यहाँ उन्हें इस्तेमाल करने का एक शर्मनाक ओवर-कॉम्प्लेक्स उदाहरण है (कमजोर इवेंट पैटर्न के लिए जो ta.speot.is नीचे वर्णित है)
बेंजोल

जवाबों:


39

मुझे निम्नलिखित तीन वास्तविक दुनिया परिदृश्यों में कमजोर संदर्भों के वैध व्यावहारिक अनुप्रयोग मिले हैं जो वास्तव में मेरे साथ व्यक्तिगत रूप से हुए हैं:

आवेदन 1: इवेंट हैंडलर

आप एक उद्यमी हैं। आपकी कंपनी WPF के लिए स्पार्क लाइन्स कंट्रोल बेचती है । बिक्री बहुत अच्छी है लेकिन समर्थन मूल्य आपको मार रहे हैं। बहुत से ग्राहक सीपीयू हॉगिंग और मेमोरी लीक की शिकायत करते हैं जब वे स्पार्क लाइनों से भरे स्क्रीन के माध्यम से स्क्रॉल करते हैं। समस्या यह है कि उनका ऐप नई स्पार्क लाइनें बना रहा है क्योंकि वे देखने में आते हैं लेकिन डेटा बाइंडिंग पुराने लोगों को कचरा एकत्र करने से रोक रही है। आप क्या करते हैं?

डेटा बाइंडिंग और आपके नियंत्रण के बीच एक कमजोर संदर्भ पेश करें ताकि अकेले डेटा बाइंडिंग आपके नियंत्रण को कचरा एकत्र होने से न रोक सके। फिर अपने नियंत्रण में एक अंतिम संयोजक जोड़ें जो एकत्र होने पर डेटा बाइंडिंग को फाड़ देता है।

आवेदन 2: परस्पर रेखांकन

आप अगले जॉन कार्मैक हैं। आपने पदानुक्रमिक उपखंड सतहों के एक सरल नए ग्राफ-आधारित प्रतिनिधित्व का आविष्कार किया है जो टिम स्वीनी के गेम को निनटेंडो Wii जैसा दिखता है। जाहिर है मैं आपको यह नहीं बताने जा रहा हूं कि यह कैसे काम करता है, लेकिन यह इस परिवर्तनशील ग्राफ पर सभी केंद्र हैं जहां एक शीर्ष के पड़ोसियों को एक में पाया जा सकता है Dictionary<Vertex, SortedSet<Vertex>>। जैसे-जैसे खिलाड़ी चलता है ग्राफ का टोपोलॉजी बदलता रहता है। केवल एक ही समस्या है: आपकी डेटा संरचना अप्राप्य उपग्रहों को बहा रही है क्योंकि यह चलती है और आपको उन्हें हटाने की आवश्यकता होती है या आप मेमोरी को लीक कर देंगे। सौभाग्य से आप एक प्रतिभाशाली व्यक्ति हैं, इसलिए आपको पता है कि एल्गोरिदम का एक वर्ग है जो विशेष रूप से अनुपलब्ध उपग्रहों का पता लगाने और इकट्ठा करने के लिए डिज़ाइन किया गया है: कचरा संग्रहकर्ता! आपने इस विषय पर रिचर्ड जोन्स का उत्कृष्ट मोनोग्राफ पढ़ालेकिन यह आपको अपने आसन्न समय सीमा के बारे में चिंतित और चिंतित छोड़ देता है। आप क्या करते हैं?

बस Dictionaryएक कमजोर हैश टेबल के साथ अपने स्थान को बदलकर आप मौजूदा जीसी को गुल्लक कर सकते हैं और यह स्वचालित रूप से आपके लिए अपने अप्राप्य सबग्राफ को इकट्ठा कर सकता है! फेरारी विज्ञापनों के माध्यम से पत्ता वापस करने के लिए।

आवेदन 3: सजा पेड़

आप एक कीबोर्ड पर एक चक्रीय कमरे की छत से लटक रहे हैं। किसी को ढूंढने से पहले आपको कुछ BATA DATA के माध्यम से 60 सेकंड का समय लगता है। आप एक सुंदर स्ट्रीम-आधारित पार्सर के साथ तैयार हुए जो विश्लेषण करने के बाद जीसी पर एएसटी के टुकड़े इकट्ठा करने के लिए निर्भर करता है। लेकिन आपको लगता है कि आपको प्रत्येक एएसटी पर अतिरिक्त मेटाडेटा Nodeकी आवश्यकता है और आपको इसकी आवश्यकता है। आप क्या करते हैं?

आप Dictionary<Node, Metadata>प्रत्येक नोड के साथ मेटाडेटा को संबद्ध करने के लिए उपयोग कर सकते हैं , लेकिन जब तक आप इसे स्पष्ट नहीं करते हैं, शब्दकोश से पुराने एएसटी नोड्स तक के मजबूत संदर्भ उन्हें जीवित और रिसाव स्मृति रखेंगे। समाधान एक कमजोर हैश तालिका है जो केवल कुंजियों के लिए कमजोर संदर्भ रखती है और कचरा कुंजी-कुंजी बाइंडिंग एकत्र करता है जब कुंजी पहुंच से बाहर हो जाती है। फिर, एएसटी नोड्स अप्राप्य हो जाते हैं, वे एकत्र किए गए कचरा होते हैं और उनके कुंजी-मूल्य बंधन को संबंधित मेटाडेटा को अनुपलब्ध छोड़ने से हटा दिया जाता है, इसलिए यह भी एकत्र हो जाता है। उसके बाद आपको अपने मुख्य लूप को समाप्त करने के बाद एयर सिक्योर के माध्यम से वापस स्लाइड करना होगा, ताकि यह याद रहे कि जैसे ही सुरक्षा व्यवस्था में बदलाव हो।

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


2
कमजोर संदर्भ अनुप्रयोग 2 के लिए काम नहीं करेगा यदि अगम्य उपग्रहों में चक्र हैं। ऐसा इसलिए है क्योंकि एक कमजोर हैश तालिका में आमतौर पर कुंजियों के कमजोर संदर्भ होते हैं, लेकिन मूल्यों के लिए मजबूत संदर्भ। आपको एक हैश तालिका की आवश्यकता होगी जो केवल तब भी मूल्यों के मजबूत संदर्भों को बनाए रखती है जबकि कुंजी अभी भी उपलब्ध है -> एपीरॉन ( ConditionalWeakTable.NET में) देखें।
डैनियल

@ डैनियल जीसी को अगम्य चक्रों को संभालने में सक्षम नहीं माना जाता है? यह कैसे होता नहीं एकत्र किया जा मजबूत संदर्भों की एक नहीं पहुंचा जा सकता चक्र जब होगा एकत्र किया?
5

ओह, मुझे लगता है कि मैं देख रहा हूं। मैंने अभी यह माना है कि ConditionalWeakTable2 और 3 का उपयोग क्या होता है जबकि अन्य पदों के कुछ लोग वास्तव में उपयोग करते हैं Dictionary<WeakReference, T>। पता नहीं क्यों-आप हमेशा WeakReferenceउन मूल्यों के साथ एक टन नल के साथ समाप्त हो जाएंगे जो किसी भी कुंजी द्वारा एक्सेस नहीं किए जा सकते हैं, भले ही आप इसे कैसे करें। Ridik।
बिंकी b ’816

@binki: "क्या जीसी को अगम्य चक्रों को संभालने में सक्षम नहीं होना चाहिए? जब मजबूत संदर्भों का एक पहुंच योग्य चक्र एकत्र नहीं किया जाएगा तो इसे कैसे एकत्र नहीं किया जाएगा?"। आपके पास अद्वितीय वस्तुओं पर एक शब्दकोष है जिसे दोबारा नहीं बनाया जा सकता है। जब आपकी कोई महत्वपूर्ण वस्तु अप्राप्य हो जाती है तो उसे कचरा एकत्र किया जा सकता है, लेकिन शब्दकोश में संबंधित मूल्य भी नहीं सोचा जाएगा कि यह सैद्धांतिक रूप से अगम्य है, क्योंकि एक सामान्य शब्दकोश इसे जीवित रखने के लिए एक मजबूत संदर्भ प्रदान करेगा। तो आप एक कमजोर शब्दकोश का उपयोग करें।
जॉन हैरोप

@ डैनियल: "कमजोर संदर्भ अनुप्रयोग 2 के लिए काम नहीं करेगा यदि अगम्य उपग्रहों में चक्र शामिल हैं। यह इसलिए है क्योंकि एक कमजोर हैश तालिका में आमतौर पर कुंजियों के कमजोर संदर्भ होते हैं, लेकिन मूल्यों के लिए मजबूत संदर्भ। आपको हैश तालिका की आवश्यकता होगी।" मूल्यों के लिए मजबूत संदर्भ बनाए रखता है जबकि कुंजी अभी भी उपलब्ध है "। हाँ। आप शायद ग्राफ को सीधे किनारों के साथ एन्कोर्स के रूप में एन्कोडिंग करना बेहतर समझते हैं, इसलिए जीसी इसे खुद ही इकट्ठा करेगा।
जॉन हैरोप

19

इन विशेषताओं को देखते हुए, मैं ऐसी स्थिति के बारे में नहीं सोच सकता जहां कमजोर संदर्भ उपयोगी होंगे, शायद कोई मुझे बता सके?

Microsoft दस्तावेज़ कमजोर ईवेंट पैटर्न

अनुप्रयोगों में, यह संभव है कि हैंडलर जो घटना स्रोतों से जुड़े होते हैं, श्रोता ऑब्जेक्ट के साथ समन्वय में नष्ट नहीं होंगे जो हैंडलर को स्रोत से जोड़ते हैं। इस स्थिति से मेमोरी लीक हो सकती है। विंडोज प्रेजेंटेशन फ़ाउंडेशन (WPF) एक डिज़ाइन पैटर्न पेश करता है जिसका उपयोग इस मुद्दे को संबोधित करने के लिए किया जा सकता है, विशेष घटनाओं के लिए एक समर्पित प्रबंधक वर्ग प्रदान करके और उस घटना के लिए श्रोताओं पर एक इंटरफ़ेस लागू करने के लिए। इस डिजाइन पैटर्न को कमजोर इवेंट पैटर्न के रूप में जाना जाता है।

...

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


वह URL ऑटो नवीनतम .NET संस्करण (वर्तमान में 4.5) का चयन करता है जिसमें 'यह विषय अब उपलब्ध नहीं है'। .NET 4.0 का चयन करने के बजाय काम करता है ( msdn.microsoft.com/en-us/library/aa970850(v=vs.100).aspx )
अधिकतम

13

मुझे पहले इसे बाहर करने दो और इसके बाद वापस आओ:

जब आप किसी ऑब्जेक्ट पर टैब रखना चाहते हैं तो एक WeakReference उपयोगी है, लेकिन आप उस ऑब्जेक्ट को एकत्र होने से रोकने के लिए अपनी टिप्पणियों को नहीं चाहते हैं

तो शुरू से शुरू करते हैं:

- अग्रिम में किसी भी अनजाने अपराध के लिए, लेकिन मैं एक पल के लिए "डिक और जेन" स्तर पर वापस आने वाला हूं क्योंकि कोई भी दर्शकों को कभी नहीं बता सकता है।

इसलिए जब आपको कोई वस्तु मिल गई है X- चलो इसे एक उदाहरण के रूप में निर्दिष्ट करते हैं class Foo- यह अपने आप पर नहीं रह सकता है (ज्यादातर सच); उसी तरह से कि "कोई आदमी एक द्वीप नहीं है", केवल कुछ ही तरीके हैं जो एक वस्तु को द्वीपवाद को बढ़ावा दे सकते हैं - हालांकि इसे सीएलआर बोलते में जीसी रूट कहा जाता है। जीसी रूट होने के नाते, या जीसी रूट के कनेक्शन / संदर्भों की एक स्थापित श्रृंखला होने के नाते, मूल रूप से यह निर्धारित करता है कि Foo x = new Foo()कचरा एकत्र होता है या नहीं ।

यदि आप अपने जीसी रूट पर वापस नहीं जा सकते हैं तो या तो ढेर या स्टैक वॉकिंग से, आप प्रभावी रूप से अनाथ हैं, और संभवतः अगले चक्र को चिह्नित / एकत्र किया जाएगा।

इस बिंदु पर, आइए कुछ भयानक-आकस्मिक उदाहरण देखें:

सबसे पहले, हमारे Foo:

public class Foo 
{
    private static volatile int _ref = 0;
    public event EventHandler FooEvent;
    public Foo()
    {
        _ref++;
        Console.WriteLine("I am #{0}", _ref);
    }
    ~Foo()
    {
        Console.WriteLine("#{0} dying!", _ref--);
    }
}

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

अब एक नजर डालते हैं FooConsumer:

public class NastySingleton
{
    // Static member status is one way to "get promoted" to a GC root...
    private static NastySingleton _instance = new NastySingleton();
    public static NastySingleton Instance { get { return _instance;} }

    // testing out "Hard references"
    private Dictionary<Foo, int> _counter = new Dictionary<Foo,int>();
    // testing out "Weak references"
    private Dictionary<WeakReference, int> _weakCounter = new Dictionary<WeakReference,int>();

    // Creates a strong link to Foo instance
    public void ListenToThisFoo(Foo foo)
    {
        _counter[foo] = 0;
        foo.FooEvent += (o, e) => _counter[foo]++;
    }

    // Creates a weak link to Foo instance
    public void ListenToThisFooWeakly(Foo foo)
    {
        WeakReference fooRef = new WeakReference(foo);
        _weakCounter[fooRef] = 0;
        foo.FooEvent += (o, e) => _weakCounter[fooRef]++;
    }

    private void HandleEvent(object sender, EventArgs args, Foo originalfoo)
    {
        Console.WriteLine("Derp");
    }
}

इसलिए हमें एक ऐसी वस्तु मिल गई है जो पहले से ही इसकी एक जीसी जड़ है। एक Fooउदाहरण पर लाचिंग - चलो इसे बाहर का परीक्षण करें:

// Our foo
var f = new Foo();

// Create a "hard reference"
NastySingleton.Instance.ListenToThisFoo(f);

// Ok, we're done with this foo
f = null;

// Force collection of all orphaned objects
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

अब, ऊपर से, आप f"संग्रहणीय" होने के लिए वस्तु-कि-एक-बार-संदर्भित-से-उम्मीद करेंगे ?

नहीं, क्योंकि एक अन्य वस्तु है जो अब इसका संदर्भ रखती है - Dictionaryउस Singletonस्थिर उदाहरण में।

ठीक है, चलो कमजोर दृष्टिकोण की कोशिश करें:

f = new Foo();
NastySingleton.Instance.ListenToThisFooWeakly(f);

// Ok, we're done with this foo
f = null;

// Force collection of all orphaned objects
// This should collect # 2 - you'll see a "#2 dying"
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

अब, जब हम अपने संदर्भ को Foo-that-was-Once-one- से जोड़ते fहैं, तो ऑब्जेक्ट के लिए अधिक "कठिन" संदर्भ नहीं होते हैं, इसलिए यह संग्रहणीय है - WeakReferenceकमजोर श्रोता द्वारा बनाया गया यह रोक नहीं पाएगा।

अच्छे उपयोग के मामले:

  • ईवेंट हैंडलर (हालाँकि इसे पहले पढ़ें: C # में कमजोर ईवेंट )

  • आपको एक ऐसी स्थिति मिली है जहाँ आप एक "पुनरावर्ती संदर्भ" (यानी, ऑब्जेक्ट A को ऑब्जेक्ट B से संदर्भित करते हैं, जो ऑब्जेक्ट A को संदर्भित करता है, जिसे "मेमोरी लीक" भी कहा जाता है) (संपादित करें: derp, बेशक यह isn है 'सच है)

  • आप वस्तुओं के संग्रह के लिए कुछ "प्रसारित" करना चाहते हैं, लेकिन आप उन्हें जीवित रखने वाली चीज नहीं बनना चाहते; एक List<WeakReference>को आसानी से बनाए रखा जा सकता है, और यहां तक ​​कि जहां हटाकर छंटाई की जा सकती हैref.Target == null


1
आपके दूसरे उपयोग के मामले के बारे में, कचरा संग्रहकर्ता परिपत्र संदर्भों को ठीक से संभालता है। "ऑब्जेक्ट ए, ऑब्जेक्ट बी को संदर्भित करता है, जो ऑब्जेक्ट ए को संदर्भित करता है" निश्चित रूप से मेमोरी लीक नहीं है।
जो डेली

@ जोडेले मैं सहमत हूँ। .NET GC एक चिह्न और स्वीप एल्गोरिथ्म का उपयोग करता है जो (मेरा मानना ​​है कि मैं इसे सही ढंग से याद कर रहा हूं) संग्रह के लिए सभी ऑब्जेक्ट्स को चिह्नित करता है और फिर "जड़ों" (स्टैक, ऑब्जेक्ट्स पर ऑब्जेक्ट्स का संदर्भ) के संदर्भों का अनुसरण करता है। । यदि कोई गोलाकार संदर्भ मौजूद है, लेकिन कोई भी वस्तु जड़ से सुलभ नहीं है, तो वस्तुएं संग्रह के लिए अचिह्नित नहीं हैं और इस प्रकार संग्रह के लिए योग्य हैं।
ta.speot.is

1
@JoeDaley - आप दोनों निश्चित रूप से, सही हैं - इसे अंत में वहाँ ले जा रहे थे ... मैं इसे संपादित करूँगा।
जेरकीबॉल

4

यहाँ छवि विवरण दर्ज करें

तार्किक लीक की तरह जो वास्तव में नीचे ट्रैक करने के लिए कठिन होते हैं, जबकि उपयोगकर्ता बस नोटिस करते हैं कि लंबे समय तक आपके सॉफ़्टवेयर को चलाने से अधिक से अधिक मेमोरी लेने और धीमी और धीमी हो जाती है जब तक वे पुनः आरंभ नहीं करते हैं? मैं नही।

विचार करें कि क्या होता है, यदि उपयोगकर्ता उपर्युक्त अनुप्रयोग संसाधन को हटाने का अनुरोध करता है, तो Thing2ऐसी घटना को ठीक से संभालने में विफल रहता है:

  1. संकेत
  2. मजबूत संदर्भ
  3. कमजोर संदर्भ

... और जिसके तहत इनमें से किसी एक को गलती से परीक्षण के दौरान पकड़ा जाएगा, और जो एक गुप्त लड़ाकू बग की तरह रडार के नीचे नहीं उड़ जाएगा। साझा स्वामित्व, अधिक से अधिक बार, एक निरर्थक विचार है।


1

अच्छे प्रभाव के लिए उपयोग किए जाने वाले कमजोर संदर्भों का एक बहुत ही गलत उदाहरण है ConditionalWeakTable , जिसका उपयोग DLR (अन्य स्थानों के बीच) में वस्तुओं के अतिरिक्त "सदस्य" को जोड़ने के लिए किया जाता है।

आप ऑब्जेक्ट को जीवित रखने के लिए तालिका नहीं चाहते हैं। यह अवधारणा केवल कमजोर संदर्भों के बिना काम नहीं कर सकती थी।

लेकिन यह मुझे इस तरह का लगता है कि कमजोर संदर्भों के लिए सभी उपयोग भाषा में जोड़े जाने के लंबे समय बाद आए, क्योंकि कमजोर संदर्भ 1.1 संस्करण के बाद से .NET का हिस्सा हैं। ऐसा लगता है कि आप कुछ जोड़ना चाहते हैं, ताकि नियतात्मक विनाश की कमी आपको एक कोने में वापस नहीं लाएगी जहां तक ​​भाषा की विशेषताएं हैं।


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

-2

यदि आपके पास C # के साथ कैश लेयर लागू है, तो यह बहुत बेहतर है कि अपने डेटा को कैश में कमजोर संदर्भों के रूप में डालें, यह आपके कैश लेयर प्रदर्शन को बेहतर बनाने में मदद कर सकता है।

विचार करें कि सत्र कार्यान्वयन के लिए दृष्टिकोण भी लागू किया जा सकता है। क्योंकि सत्र लंबे समय तक जीवित रहने वाला सबसे अधिक समय होता है, यह कुछ मामला हो सकता है जब आपके पास नए उपयोगकर्ता के लिए कोई मेमोरी नहीं है। उस स्थिति में कुछ और उपयोगकर्ता सत्र ऑब्जेक्ट को तब हटाना बेहतर होगा जब OutOfMemoryException को फेंक दिया जाए।

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


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

1
लेकिन बड़ी वस्तुओं के बारे में आपके दूसरे बिंदु के लिए, MSDN डॉक्टर बताता है कि लंबे समय तक कमजोर संदर्भों से आपको किसी वस्तु को फिर से बनाने की अनुमति मिलती है, यह स्थिति अप्रत्याशित रहती है। यदि आप इसे हर बार स्क्रैच से फिर से बनाने जा रहे हैं, तो कमजोर संदर्भ का उपयोग करके परेशान क्यों करें जब आप इसे मांग पर बनाने के लिए एक फ़ंक्शन / विधि को कॉल कर सकते हैं और एक क्षणिक उदाहरण वापस कर सकते हैं?

एक ऐसी स्थिति है जहां कैशिंग मददगार है: यदि कोई अक्सर अपरिवर्तनीय वस्तुओं का निर्माण कर रहा होगा, जिनमें से कई समान होंगे (उदाहरण के लिए एक फ़ाइल से कई पंक्तियों को पढ़ना जिसमें कई डुप्लिकेट होने की उम्मीद है) प्रत्येक स्ट्रिंग को एक नई वस्तु के रूप में बनाया जाएगा , लेकिन यदि कोई रेखा दूसरी पंक्ति से मेल खाती है जिसमें एक संदर्भ पहले से मौजूद है, तो नई आवृत्ति को छोड़ देने पर स्मृति दक्षता में सुधार किया जा सकता है और पहले से मौजूद उदाहरण के संदर्भ को प्रतिस्थापित किया जाता है। ध्यान दें कि यह प्रतिस्थापन उपयोगी है क्योंकि अन्य संदर्भ को वैसे भी रखा जा रहा है। यदि यह कोड नहीं था तो नया रखना चाहिए।
सुपरकाट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.