1.如果我有類似Foo o = new Foo();裏面的方法,是否 的意思是每次計時器滴答, 我正在創建一個新的對象和一個新的 引用該對象?
是的。
2.如果我有字符串foo = null,然後我只是把時間放在foo中, 是否與上面相同?
如果你問的行爲是否相同,那麼是的。
3.Does垃圾收集永遠刪除對象和基準或 對象的持續創建和 留在記憶?
這些對象所使用的內存在引用被視爲未被使用後肯定會被收集。
4.如果我只是聲明Foo o;而不是指向任何實例,當方法結束時不是 ?
不,因爲沒有對象被創建,所以沒有收集對象(處置不是正確的詞)。
5。如果我想確保一切都被刪除,什麼是 做的最好的方式,
如果對象的類實現IDisposable
那麼你一定要儘快撥打貪婪Dispose
。 using
關鍵字使得這個更容易,因爲它以自動異常安全的方式調用Dispose
。
除此之外,除了停止使用該對象之外,實際上沒有其他事情需要做。如果引用是局部變量,則當它超出範圍時,它將有資格收集。 如果它是一個類級別的變量,那麼您可能需要分配null
才能使其符合條件。
這在技術上是不正確的(或者至少有點誤導)。一個對象在超出範圍之前可能有資格收集。 CLR經過優化,可在檢測到不再使用引用時收集內存。在極端情況下,即使其中一個方法仍在執行,CLR也可以收集一個對象!
更新:
這裏是證明了GC將收集的對象,即使他們可能仍然在範圍內的例子。您必須編譯Release版本並在調試器之外運行。
static void Main(string[] args)
{
Console.WriteLine("Before allocation");
var bo = new BigObject();
Console.WriteLine("After allocation");
bo.SomeMethod();
Console.ReadLine();
// The object is technically in-scope here which means it must still be rooted.
}
private class BigObject
{
private byte[] LotsOfMemory = new byte[Int32.MaxValue/4];
public BigObject()
{
Console.WriteLine("BigObject()");
}
~BigObject()
{
Console.WriteLine("~BigObject()");
}
public void SomeMethod()
{
Console.WriteLine("Begin SomeMethod");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("End SomeMethod");
}
}
在我的機器,而SomeMethod
仍在執行終結運行!
如果沒有該根對象的引用,對象的方法會如何? – Yaur 2011-05-20 06:06:44
@Yaur:好問題:考慮一個不使用其他實例成員(變量或方法)的實例方法。這意味着只需要提取對象引用來傳遞'this'引用。在此之後,只要CLR可以檢測到該對象即使它仍然可以被植根,它也不會在以後使用,在技術上符合條件。 – 2011-05-20 13:12:44
@Brian Gideon我明白你的觀點,但我對此表示懷疑,因爲CLR使用mark-and-sweep來確定GC是否符合這種情況,或者該對象甚至在技術上符合垃圾回收的「合格條件」。但無論如何,這是一個足夠有趣的案例來做一些測試。 – Yaur 2011-05-20 13:34:52