আমি এটি প্রথমে রাখি এবং এটিতে ফিরে আসি:
আপনি যখন কোনও বস্তুতে ট্যাব রাখতে চান তখন একটি WeakReferences কার্যকর হয়, তবে আপনি চান না যে আপনার পর্যবেক্ষণগুলি সেই অবজেক্টটি সংগ্রহ করা থেকে আটকাবে
সুতরাং আসুন শুরু থেকে শুরু করা যাক:
কোনও অনিচ্ছাকৃত অপরাধের জন্য অগ্রিম বিজ্ঞাপনগুলি, তবে আমি কোনও মুহুর্তের জন্য "ডিক এবং জেন" স্তরে ফিরে যাব কারণ কেউ কখনই শ্রোতাদের বলতে পারে না।
সুতরাং যখন আপনি কোনও জিনিস পেয়েছেন X
- আসুন এটির উদাহরণ হিসাবে নির্দিষ্ট করুন class Foo
- এটি নিজেরাই লাইভ করতে পারে না (বেশিরভাগ সত্য); "কোনও মানুষই দ্বীপ নয়" একইভাবে, কোনও বস্তু দ্বীপপুঞ্জে উন্নীত করতে পারে এমন কয়েকটি উপায় রয়েছে - যদিও এটি সিএলআর ভাষায় জিসি রুট বলে। জিসি রুট হওয়া বা কোনও জিসি রুটের সাথে সংযোগ / রেফারেন্সের প্রতিষ্ঠিত চেইন থাকা মূলত যা নির্ধারণ করে তা Foo x = new Foo()
আবর্জনা সংগ্রহ করা যায় কিনা not
আপনি যদি গিস বা স্ট্যাক হাঁটার মাধ্যমে কিছু জিসি রুটে ফিরে যেতে না পারেন তবে আপনি কার্যকরভাবে এতিম হয়েছেন এবং পরবর্তী চক্রটি সম্ভবত চিহ্নিত / সংগ্রহ করা হবে।
এই মুহুর্তে, আসুন কয়েকটি ভয়াবহ-নিয়ন্ত্রিত উদাহরণগুলি দেখুন:
প্রথম, আমাদের 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
-একবার-এর সাথে আমাদের রেফারেন্সটি ফাঁকি দিয়ে f
দেখি তখন অবজেক্টটির জন্য আর কোনও "শক্ত" রেফারেন্স থাকে না, সুতরাং এটি সংগ্রহযোগ্য - WeakReference
দুর্বল শ্রোতার দ্বারা নির্মিত তা বাধা দেয় না।
ভাল ব্যবহারের ক্ষেত্রে:
ইভেন্ট হ্যান্ডলার (যদিও এটি প্রথম পড়ুন: সি # তে দুর্বল ইভেন্টগুলি )
আপনি এমন একটি পরিস্থিতি পেয়েছেন যেখানে আপনি "পুনরাবৃত্ত রেফারেন্স" তৈরি করতে পারেন (যেমন, অবজেক্ট এ অবজেক্ট বিকে বোঝায়, যা অবজেক্ট এ কে বোঝায়, এটি "মেমরি লিক" হিসাবেও পরিচিত) (সম্পাদনা: ডের্প, অবশ্যই এই আইএনএন সত্য নয়)
আপনি অবজেক্টের সংকলনে কিছু "সম্প্রচার" করতে চান, তবে আপনি এগুলি বাঁচিয়ে রাখার জিনিসটি হতে চান না; একটি List<WeakReference>
সহজেই বজায় রাখা যায়, এবং যেখানে সরিয়ে দিয়ে ছাঁটাই করা যায়ref.Target == null