一、托管代碼/非托管代碼
C#代碼通過C#編譯器編譯成程序集,程序集由微軟中間語言組成,CLR會為程序集開辟一個應用程序域,程序集就是運行在這個應用程序域裡面的,應用程序域是相互獨立的,互不影響。
托管代碼:被CLR管理的代碼。
非托管代碼:不被CLR管理的代碼。
分配在棧空間的變量,一旦執行完成其所在的作用域(即大括號范圍)就會被CLR回收。
分配在堆裡面的對象,當沒有任何變量引用它的時候,這個對象就被標記為“垃圾對象”(沒有變量引用它),等待垃圾回收器回收。
Eg:
Person p= p=;
二、GC
GC會定時清理堆裡面的垃圾對象,GC的清理頻率程序員無法決定,CLR會自動控制。當一個對象標記為垃圾的時候,這個對象不一定會被立即回收。
三、析構函數
1、不能有訪問修飾符,不能有參數。
2、在對象被垃圾回收器回收的時候,析構函數被GC自動調用。
3、執行一些清理善後的操作的時候。
~ Console.WrilteLine( }
四、代
當堆裡面的對象有1W個的時候,GC是不是循環1W次來判斷是否為“垃圾對象”,然後對其進行回收呢?答案是否定的,微軟根據實際需要采用了很多種算法來清理堆裡面的垃圾對象,其中很重要的一種算法就是“代”。堆裡面總共有3代,譬如,當程序運行時,有對象需要存儲在堆裡面,GC就會創建第1代(假設空間大小為256K),對象就會存儲在第0代裡面,當程序繼續運行,運行到第0代的大小不足以存放對象,這時候就就會創建第1代(假設空間為10M),GC就會把第0代裡面的“垃圾對象”清理掉,把“活著”的對象放在第1代,這時候第0代就空了,用於存放新來的對象,當第0代滿了的時候,就會繼續執行以上操作,隨著程序的運行,第1代不能滿足存放要求,這時候就會創建第2代,清理方式如上相同。下圖用於理解以上描述的過程:
GC.GetGeneration(P)得到指定的對象對應的代,總共有三代。
GC.Collect();//讓垃圾回收器對所有的代進行回收。
GC.Collect(1)//回收第0代和第1代回收。
~ Main(= + GC.GetGeneration(p1)); GC.Collect(); Console.WriteLine( + Console.WriteLine( + Console.WriteLine( += ; GC.Collect();
結果:
注:以上文章均屬軟謀原創,如需轉載請注明出處!