在.NET 中自動垃圾管理 是垃圾回收器來做的。GC自動完成對託管堆的全權管理,然後把所有的事情都交給GC來做。
對於.NET 程式師及基於性能安全考慮有必要對GC工作原理,執行過程進行深層次探討。
垃圾回收機制從以下幾個方面來討論:
1,什麼樣的物件GC認為 是垃圾呢。
2,GC如何來回收垃圾呢。
3,GC何時來回收垃圾呢。
4,GC回收之後要操作些什麼呢。
好。那我們一一來揭曉謎底吧。
l 什麼樣的物件被GC認為是垃圾呢?
一個物件成為垃圾:那就說明這個物件不在被任何使用。
其實每個物件 都有一組指標,針指向拖管堆的存儲位置,由JIT編譯器與CLR運行時維護根指標清單,包括全
局變數、靜態變數、區域變數和寄存器指標等
class A { private B objB; public A(B o) { objB = o; } ~A() { Console.WriteLine("Destory A."); }}
class B { private C objC; public B(C o) { objC = o; } ~B() { Console.WriteLine("Destory B."); } }
class C { ~C() { Console.WriteLine("Destory C."); } }
public class Test_GCRun
{
public static void Main()
{ A a = new A(new B(new C())); //強制執行垃圾回收 GC.Collect(0); GC.WaitForPendingFinalizers();
}
在上述執行中,當創建類型A的物件a時,在託管堆中將新建類型B的實例(假設表示為objB)和類型C的實例(假設表示為objC),
並且這幾個物件之間保存著一定的聯繫。而區域變數a則相當於一個應用程式的根,假設其在託管堆中對應的實例表示為objA,則當前的引用關係可以
l 何時回收?
垃圾收集器週期性的執行記憶體清理工作,一般在以下情況出現時垃圾收集器將會啟動:
(1)記憶體不足溢出時,更確切地應該說是第0代物件充滿時。
(2)調用GC.Collect方法強制執行垃圾回收。
(3)Windows報告記憶體不足時,CLR將強制執行垃圾回收。
(4)CLR卸載AppDomain時,GC將對所有代齡的物件執行垃圾回收。
(5)其他情況,例如實體記憶體不足,超出短期存活代的記憶體段門限,運行主機拒絕分配記憶體等
作為.NET開發人員的我們不必要自己寫任何代碼來管理整個Application 中各個物件的生命週期,CLR知道何時去執行垃圾收集工作來
滿足application 的記憶體需求,當GC釋放記憶體之前它會檢查是否要執行非拖管資源的清理工作.Microsoft 強烈不建議通過GC.collect方法來強制回收垃圾,,這樣會擾亂GC垃圾回收的工作原理.
只有明確有大物件不在引用時,才可以用GC.collect 來釋放空間
2,回收之後它又會做什麼呢。。。
GC回收之後中,會留下很多物件的空洞,為避免託管堆的碎片,會壓縮託管堆,進行重新分配,就像我們經常執行磁碟重組一樣。具體操作:GC會找到一塊大的連續區域,將未被回收的對
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()