假設我有一個C#方法是這樣的:(顯然不是真正的代碼)方法本地.NET對象何時符合GC要求?
byte[] foo()
{
var a = MethodThatReturns500mbObject();
var b = MethodThatReturns200mbObject(a);
byte[] c = MethodThatReturns150mbByteArray(b);
byte[] d = UnwiselyCopyThatHugeArray(c);
return d;
}
你可以通過命名猜測,由這些方法返回的對象是巨大的。儘管前兩個對象由數百萬個較小的對象組成,而不是像後兩個數組那樣的巨大塊,但每個內存需要數百兆字節的RAM。
我們將盡快將其優化爲一個流式解決方案,但同時我想確保至少我們不會阻止早期對象的GC,同時執行代碼來生成後面的對象。
我的問題是:只要MethodThatReturns200mbObject(a)返回,對象a
是否有資格獲得GC?如果沒有,讓GC知道現在有500MB存在的最好方法是什麼?
我的問題的核心是.NET GC確定「這個對象沒有引用」是否足夠聰明,知道MethodThatReturns200mbObject(a)
返回後不能引用a
。即使var a
仍然在理論上可用於後面的代碼,a
不在方法的第二行下面的任何地方引用。理論上,編譯器可以讓GC知道a
未被引用。但在實踐中,我不確定它是如何表現的。你知道嗎?
'GC.KeepAlive()'不會有多大用處,如果所有的變量都已經保持活着直到其範圍結束。 –
在發佈模式中,是的,編譯器非常聰明,可以在不再使用垃圾收集的時候將'a'標記爲垃圾收集的候選對象。 [這個答案](https://stackoverflow.com/questions/17130382/understanding-garbage-collection-in-net/17131389#17131389)可能也有用 – Rob