public class MyClass {
private static MyClass heldInstance;
public MyClass() {
heldInstance = this;
}
}
假設MyClass的實例的根源並非是任何其他方式,將這裏的私人靜態參考防止它被垃圾回收?在靜態字段中引用自身的類是否可以垃圾收集?
public class MyClass {
private static MyClass heldInstance;
public MyClass() {
heldInstance = this;
}
}
假設MyClass的實例的根源並非是任何其他方式,將這裏的私人靜態參考防止它被垃圾回收?在靜態字段中引用自身的類是否可以垃圾收集?
您發佈的類將不被垃圾收集。你可以給它一個控制檯輸出終結測試:
public class MyClass
{
private static MyClass heldInstance;
public MyClass()
{
heldInstance = this;
}
~MyClass()
{
Console.WriteLine("Finalizer called");
}
}
class Program
{
static void Main(string[] args)
{
var x = new MyClass(); // object created
x = null; // object may be eliglible for garbage collection now
// theoretically, a GC could happen here, but probably not, with this little memory used
System.Threading.Thread.Sleep(5000);
// so we force a GC. Now all eligible objects will definitely be collected
GC.Collect(2,GCCollectionMode.Forced);
//however their finalizers will execute in a separate thread, so we wait for them to finish
GC.WaitForPendingFinalizers();
System.Threading.Thread.Sleep(5000);
Console.WriteLine("END");
}
}
輸出將是:
END
Finalizer called
這意味着該類只在應用程序的最終拆除被採集,不在正規垃圾收集期間。
如果你創建這個類的多個實例是這樣的:
var x = new MyClass();
x = new MyClass();
x = new MyClass();
x = new MyClass();
然後所有除最近的一個將被垃圾收集。
你會得到
Finalizer called
Finalizer called
Finalizer called
END
Finalizer called
請注意,這僅僅是因爲'heldInstance'是靜態的。 「MyClass」的一個實例具有對自身的引用這一事實沒有什麼特別之處。所以,是的「引用自己的類」可以被垃圾回收。但是,示例中的類不能。 – dgvid 2013-02-26 22:01:08
垃圾回收器確定哪些對象是可達和將收集那些沒有。要確定一個對象是否可達,收集器將與所謂的根開始。其中根是當前計算堆棧上的東西,也靜態字段。收集器將遵循從根到對象的引用,並從這樣的對象到任何其他對象,等等。以這種方式訪問的每個對象都是可訪問的,因此將保持活動狀態。
在你的情況下,靜態字段是垃圾收集器的根之一,因此它永遠不會收集由該字段引用(間接)的任何對象。但是,如果你的字段設置爲null
則該場不再引用實例,該實例可以收集。
可能的重複[做靜態成員有沒有垃圾收集?](http://stackoverflow.com/questions/6600093/do-static-members-ever-get-garbage-collected)編輯:總之,不,我不相信會。例如,在您發佈的代碼中,沒有任何理由說明爲什麼公共構造函數不能擁有if(heldInstance == null)'除此之外,_instances_中只有持有的引用自身會自己收集_eventually_一旦它確定它不再可訪問,由GC決定。 – 2013-02-26 21:37:42
是的,它們在AppDomain被卸載之前收集。這是無關緊要的,除非班上有終結者。 – 2013-02-26 21:45:42
該類的靜態字段所引用的實例*同等級*的事實是無關緊要的。靜態字段是根;他們會保留你放入它們的任何東西,而不管它的類型如何。 – 2013-02-26 22:11:15