在 C# 程式設計中,只要物件又被任何一個或以上的物件變數參考到的時候,並且記憶體回收機制被觸發執行的時候,這些物件是不被回收的。
若此時,我們採用了弱勢參考方式,則這些物件就會被記憶體機制回收。
底下為這次的測試專案原始碼:
範例原始碼
public class MyClass
{
public string Name { get; set; }
public MyClass(string name)
{
Name = name;
Console.WriteLine($"----------> MyClass類別產生一個物件 : {Name}");
}
~MyClass()
{
Console.WriteLine($"==========> MyClass類別的一個物件被記憶體回收了 : {Name}");
}
}
class Program
{
static void Main(string[] args)
{
// 正常參考一個物件,只要該參考持續存在,該物件就不會被記憶體回收
MyClass strongReference = new MyClass("Strong Reference Object") ;
// 表示弱式參考,即在參考物件的同時,仍允許系統透過記憶體回收來回收該物件。
WeakReference weakReference = new WeakReference(new MyClass("Weak Reference Object"));
Console.WriteLine($"正常使用的參考物件為 {strongReference.Name}");
Console.WriteLine($"弱式參考物件是否還存在 {weakReference.IsAlive}");
Console.WriteLine($"弱式參考物件為 {(weakReference.Target as MyClass).Name}");
Console.WriteLine("Press any key for continuing...");
Console.ReadKey();
Console.WriteLine("強制進行記憶體回收,等候三秒鐘...");
GC.Collect(2);
Thread.Sleep(3000);
Console.WriteLine($"正常使用的參考物件為 {strongReference.Name}");
Console.WriteLine($"弱式參考物件是否還存在 {weakReference.IsAlive}");
Console.WriteLine("Press any key for continuing...");
Console.ReadKey();
ReAccessWeakReference(strongReference, weakReference);
Console.WriteLine($"正常使用的參考物件為 {strongReference.Name}");
Console.WriteLine($"弱式參考物件是否還存在 {weakReference.IsAlive}");
Console.WriteLine($"弱式參考物件為 {(weakReference.Target as MyClass).Name}");
Console.WriteLine("Press any key for continuing...");
Console.ReadKey();
}
static void ReAccessWeakReference(MyClass strongReference, WeakReference weakReference)
{
if (weakReference.Target == null)
{
Console.WriteLine("因為弱式參考的物件不存在了,所以重新取得該弱式參考物件...");
weakReference.Target = new MyClass("再次產生的 Weak Reference Object");
}
}
}
程式執行結果
----------> MyClass類別產生一個物件 : Strong Reference Object
----------> MyClass類別產生一個物件 : Weak Reference Object
正常使用的參考物件為 Strong Reference Object
弱式參考物件是否還存在 True
弱式參考物件為 Weak Reference Object
Press any key for continuing...
強制進行記憶體回收,等候三秒鐘...
==========> MyClass類別的一個物件被記憶體回收了 : Weak Reference Object
正常使用的參考物件為 Strong Reference Object
弱式參考物件是否還存在 False
Press any key for continuing...
因為弱式參考的物件不存在了,所以重新取得該弱式參考物件...
----------> MyClass類別產生一個物件 : 再次產生的 Weak Reference Object
正常使用的參考物件為 Strong Reference Object
弱式參考物件是否還存在 True
弱式參考物件為 再次產生的 Weak Reference Object
Press any key for continuing...
程式運行說明
首先,我們定義一個非常簡單的類別,在這個類別,我們建立一個有參數的建構式,用來建立該物件之用,當該物件被建立的時候,會在控制台中顯示該物件已經產生的訊息;另外,我們也建立解構函式,當該物件被記憶體回收的時候,也會在控制台中顯示該物件已經被回收的訊息。
在程式一開始執行的時候,我們建立兩個物件,一個是一般參考的物件,一個為弱式參考物件。
然後,我們確認這兩個物件都存在於系統中,也就是我們可以透過程式來進行存取這兩個物件。
// 正常參考一個物件,只要該參考持續存在,該物件就不會被記憶體回收
MyClass strongReference = new MyClass("Strong Reference Object") ;
// 表示弱式參考,即在參考物件的同時,仍允許系統透過記憶體回收來回收該物件。
WeakReference weakReference = new WeakReference(new MyClass("Weak Reference Object"));
接著,我們強制執行記憶體回收機制,並且要等候三秒鐘(這是要讓背景記憶體回收工作可以順利完成,因為是在背景執行緒中運行,我們並無法可以確實掌握到這樣的執行工作何時可以完成。
之後,我們確認屬性
IsAlive
是否為 false
,這表示該弱式參考的物件已經不存在於系統上(也就是被回收了)。
若我們這個時候想要繼續使用這個物件,我們可以使用敘述
weakReference.Target == null
確認物件是否還存在,若沒有,我們就可以再度產生該物件,這樣,我們還是可以繼續透過弱式參考的方式,存取該物件。
最後,我們可以從控制台畫面中,看到建立物件與回收物件行為發生的時候的訊息,這樣,我們便可以得到這些測試物件是有備確實建立與回收。