C#垃圾回收機(jī)制的詳細(xì)介紹
一、托管代碼/非托管代碼
C#代碼通過(guò)C#編譯器編譯成程序集,程序集由微軟中間語(yǔ)言組成,CLR會(huì)為程序集開(kāi)辟一個(gè)應(yīng)用程序域,程序集就是運(yùn)行在這個(gè)應(yīng)用程序域里面的,應(yīng)用程序域是相互獨(dú)立的,互不影響。
托管代碼:被CLR管理的代碼。
非托管代碼:不被CLR管理的代碼。
分配在棧空間的變量,一旦執(zhí)行完成其所在的作用域(即大括號(hào)范圍)就會(huì)被CLR回收。
分配在堆里面的對(duì)象,當(dāng)沒(méi)有任何變量引用它的時(shí)候,這個(gè)對(duì)象就被標(biāo)記為“垃圾對(duì)象”(沒(méi)有變量引用它),等待垃圾回收器回收。
Eg:
Person p=new Person();
p=null;//p這時(shí)候沒(méi)有指向任何對(duì)象空間,此時(shí)為“垃圾對(duì)象”。
二、GC
GC會(huì)定時(shí)清理堆里面的垃圾對(duì)象,GC的清理頻率程序員無(wú)法決定,CLR會(huì)自動(dòng)控制。當(dāng)一個(gè)對(duì)象標(biāo)記為垃圾的時(shí)候,這個(gè)對(duì)象不一定會(huì)被立即回收。
三、析構(gòu)函數(shù)
1、不能有訪問(wèn)修飾符,不能有參數(shù)。
2、在對(duì)象被垃圾回收器回收的時(shí)候,析構(gòu)函數(shù)被GC自動(dòng)調(diào)用。
3、執(zhí)行一些清理善后的操作的時(shí)候。
class Person
{
~Person()
{
Console.WrilteLine("我是析構(gòu)函數(shù)");
}
}
四、代
當(dāng)堆里面的對(duì)象有1W個(gè)的時(shí)候,GC是不是循環(huán)1W次來(lái)判斷是否為“垃圾對(duì)象”,然后對(duì)其進(jìn)行回收呢?答案是否定的,微軟根據(jù)實(shí)際需要采用了很多種算法來(lái)清理堆里面的垃圾對(duì)象,其中很重要的一種算法就是“代”。堆里面總共有3代,譬如,當(dāng)程序運(yùn)行時(shí),有對(duì)象需要存儲(chǔ)在堆里面,GC就會(huì)創(chuàng)建第1代(假設(shè)空間大小為256K),對(duì)象就會(huì)存儲(chǔ)在第0代里面,當(dāng)程序繼續(xù)運(yùn)行,運(yùn)行到第0代的大小不足以存放對(duì)象,這時(shí)候就就會(huì)創(chuàng)建第1代(假設(shè)空間為10M),GC就會(huì)把第0代里面的“垃圾對(duì)象”清理掉,把“活著”的對(duì)象放在第1代,這時(shí)候第0代就空了,用于存放新來(lái)的對(duì)象,當(dāng)?shù)?代滿了的時(shí)候,就會(huì)繼續(xù)執(zhí)行以上操作,隨著程序的運(yùn)行,第1代不能滿足存放要求,這時(shí)候就會(huì)創(chuàng)建第2代,清理方式如上相同。下圖用于理解以上描述的過(guò)程:

GC.GetGeneration(P)得到指定的對(duì)象對(duì)應(yīng)的代,總共有三代。
GC.Collect();//讓垃圾回收器對(duì)所有的代進(jìn)行回收。
GC.Collect(1)//回收第0代和第1代回收。
class Program
{
~Program()
{
Console.WriteLine("我是析構(gòu)函數(shù)");
}
static void Main(string[] args)
{
Program p1 = new Program();
Console.WriteLine("p對(duì)象所在的代:" + GC.GetGeneration(p1));//處在第0代
GC.Collect();//所有代清除了,包括第0代,這時(shí)候存活的對(duì)象就存在在第1代了。
Console.WriteLine("p對(duì)象所在的代:" + GC.GetGeneration(p1));
GC.Collect();//所有代清除了,包括第0代第1代,這時(shí)候存活的對(duì)象就存在在第2代了。
Console.WriteLine("p對(duì)象所在的代:" + GC.GetGeneration(p1));
GC.Collect();//最多只有3代
Console.WriteLine("p對(duì)象所在的代:" + GC.GetGeneration(p1));
p1 = null;//p這時(shí)候在第2代了
GC.Collect(2);//這時(shí)候p1就被回收掉了。
Console.ReadKey();
}
}
結(jié)果:

相關(guān)文章
C#使?XmlReader和XmlWriter操作XML?件
這篇文章介紹了C#使?XmlReader和XmlWriter操作XML?件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06自定義實(shí)現(xiàn)Json字符串向C#對(duì)象轉(zhuǎn)變的方法
自定義實(shí)現(xiàn)Json字符串向C#對(duì)象轉(zhuǎn)變的方法,需要的朋友可以參考一下2013-03-03C#?二進(jìn)制序列化和反序列化的具體實(shí)現(xiàn)
本文主要介紹了C#?二進(jìn)制序列化和反序列化的具體實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06