यहां ऑब्जेक्ट अंतिमकरण और संग्रह C#/.NET में संग्रह के बारे में एक अकादमिक प्रश्न है। पृष्ठभूमि पढ़ने सी # भाषा स्पेक, स्वचालित मेमोरी प्रबंधन की धारा 3.9 है।ऑब्जेक्ट को अंतिम रूप देने पर कमजोर व्यवहार व्यवहार लेकिन अभी तक कचरा एकत्र नहीं किया गया
जब किसी ऑब्जेक्ट के स्पष्ट संदर्भ नहीं होते हैं, तो यह कचरा एकत्र हो सकता है। यह "विनाश के लिए पात्र" बन जाता है। भविष्य में किसी बिंदु पर (उदाहरण के लिए यदि आप कचरा संग्रह को मजबूर करते हैं), ऑब्जेक्ट का विनाशक चलाया जाएगा।
विनाशक में, यदि आप ऑब्जेक्ट का संदर्भ सहेजते हैं, तो ऑब्जेक्ट को अंतिम रूप दिया जाएगा, लेकिन संग्रह के लिए योग्य नहीं होगा। यह उस स्थिति में एक वस्तु हो सकता है जहां इसे अंतिम रूप दिया गया है, लेकिन एकत्र नहीं किया गया है। Spec के सेक्शन 3.9 का एक उदाहरण है।
इस बिंदु पर, वस्तु वास्तव में अभी भी जीवित है, क्योंकि यह अभी तक कचरा एकत्र नहीं किया गया है। हालांकि, ऑब्जेक्ट का जिक्र करते हुए वीक रेफरेंस झूठ के इस्लाइव मान को इंगित करता है, यह दर्शाता है कि वस्तु एकत्र की गई है।
मूल प्रश्न यह है - IsAlive संपत्ति वास्तव में रिपोर्टिंग क्या है? हम जानते हैं कि हम इस संपत्ति के लिए सही मूल्य पर भरोसा नहीं कर सकते हैं, क्योंकि इसे पढ़ने के तुरंत बाद मूल्य गलत हो सकता है। लेकिन झूठ का मूल्य भरोसेमंद है और यह इंगित करने के लिए है (दस्तावेज़ीकरण के अनुसार) कि वस्तु कचरा इकट्ठा किया गया है। तो IsAlive संपत्ति हमें इस मामले में क्या बता रही है? कड़ाई से नहीं कि वस्तु कचरा एकत्रित किया गया है, क्योंकि हम मानते हैं कि वस्तु अंतिम रूप से एकत्रित स्थिति में है।
व्यवहार दिखाने के लिए यहां एक नमूना है।
public class Dog
{
public static Dog KeepDogRef;
public string Name { get; set; }
public Dog(string name)
{
Name = name;
}
~Dog()
{
Console.WriteLine("Dog destructor for " + Name + " called");
Dog.KeepDogRef = this;
}
public void Bark()
{
Console.WriteLine(Name + " : Woof");
}
}
और मुख्य कार्यक्रम के लिए कोड। यदि आप कोड चलाते हैं, तो आप देखेंगे कि मूल WeakReference रिपोर्ट IsAlive को झूठी के रूप में, ऑब्जेक्ट का पुनर्गठन करने के बाद भी।
static void Main()
{
Dog dog = new Dog("Bowser");
WeakReference dogRef = new WeakReference(dog);
// Unref Bowser, now eligible for destruction
dog = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Bowser no longer alive
Console.WriteLine(string.Format("Object still alive: {0}", dogRef.IsAlive));
// Bowser alive again
Dog newRef = Dog.KeepDogRef;
newRef.Bark();
}
}
यह उत्तर माना जाता है। एक कमजोर कमजोर संदर्भ के लिए, कमजोर संदर्भ के लक्ष्य को अंतिम रूप देने के रूप में जल्द ही शून्य हो जाता है। एक लंबे कमजोर संदर्भ के लिए, जब वस्तु वास्तव में एकत्र की जाती है तो यह केवल शून्य हो जाती है। एमएसडीएन दस्तावेज इस पर थोड़ा गंदा है। लघु बनाम लंबे समय तक दस्तावेज़ीकरण स्पष्ट है, लेकिन IsAlive संपत्ति का दस्तावेज़ीकरण पूरी तरह सटीक नहीं है, जिसमें यह इंगित करता है कि ऑब्जेक्ट एकत्र होने पर IsAlive झूठी हो जाती है।तकनीकी रूप से, कम कमजोर संदर्भों के लिए, यह केवल तभी झूठ बोलता है जब ऑब्जेक्ट को अंतिम रूप दिया गया है, लेकिन वास्तव में इसे एकत्र करने से पहले। –
@ सेनसेक्स्टन: थोड़ा सुधार: जैसे ही सिस्टम नोटिस करता है कि ऑब्जेक्ट संग्रह के लिए योग्य होगा लेकिन अंतिमकर्ता के अस्तित्व के लिए कमजोर संदर्भ को अमान्य कर दिया गया है, और इसे उन वस्तुओं की सूची में जोड़ता है जिनके अंतिमकरण विधियों को पहले चलाना चाहिए अवसर। फाइनलर आमतौर पर उसके बाद बहुत जल्द चलाया जाएगा, लेकिन यह मनमाने ढंग से देरी हो सकती है। ऑब्जेक्ट को लक्षित करने वाले किसी भी छोटे 'वीक रेफरेंस' को ऑब्जेक्ट को छोड़ दिया जाएगा, जैसे ही ऑब्जेक्ट को त्याग दिया गया था, हालांकि, जब अंतिम रूपकर्ता अंतिम रूप से चलता है। – supercat
बीटीडब्ल्यू, एक बदसूरत क्विर्क, जो विशेष रूप से लंबे कमजोर संदर्भों से परेशान है, यह है कि एक कमजोर संदर्भ जो अंतिमकरण के लिए योग्य हो जाता है, को अमान्य कर दिया जाएगा, भले ही 'वीक रेफरेंस' दोनों के संदर्भ और उसके लक्ष्य अभी भी मौजूद हैं *। इस वजह से, कोड यह सुनिश्चित करने के लिए एक लंबे कमजोर संदर्भ का उपयोग करना चाहता है कि एक वस्तु अच्छी तरह से है और वास्तव में मृत को 'वीक रेफरेंस' के लिए कहीं भी एक स्थिर संदर्भ बनाने की आवश्यकता हो सकती है, और कुछ अन्य वस्तुएं समय-समय पर निर्धारित करती हैं कि 'वीक रेफरेंस' अभी भी कुछ भी उपयोगी कर रहा है और स्थिर होने पर स्थिर संदर्भ को मार डालो। – supercat