本篇用來梳理對(duì)象的創(chuàng)建、垃圾的回收,以及非托管資源的手動(dòng)處理。
→首先運(yùn)行應(yīng)用程序,創(chuàng)建一個(gè)Windows進(jìn)程。
→CLR創(chuàng)建一塊連續(xù)的虛擬地址空間,這個(gè)地址空間就是托管堆。而且,這個(gè)地址空間最初并沒有對(duì)應(yīng)的物理存儲(chǔ)空間。
虛擬地址空間分成2段。一個(gè)區(qū)段是普通堆,也叫GC堆,大小小于85000字節(jié)的引用類型對(duì)象的實(shí)例被分配在這里;另一個(gè)是大對(duì)象堆,大小大于等于85000字節(jié)的引用類型對(duì)象的實(shí)例被分配在這里。
對(duì)于客戶端應(yīng)用程序,每個(gè)區(qū)段的大小大致是16MB;對(duì)于服務(wù)端應(yīng)用程序,每個(gè)區(qū)段的大小大致是64MB。另外,每個(gè)區(qū)段的大小還會(huì)因CPU的數(shù)量,是否是32位或64位操作系統(tǒng)而各異。
隨著每個(gè)區(qū)段被裝滿對(duì)象,CLR會(huì)分配更多的區(qū)段,直到整個(gè)進(jìn)程空間都滿了為止,每個(gè)進(jìn)程可使用4GB的內(nèi)存。
托管堆上維護(hù)著一個(gè)指針NextObjPtr,指向下一個(gè)對(duì)象在托管堆上分配的位置。
托管堆根據(jù)存儲(chǔ)信息的不同分為垃圾回收堆GC Heap和加載堆Loader Heap。垃圾回收堆GC Heap存儲(chǔ)對(duì)象實(shí)例,受GC管理;加載堆Loader Heap存儲(chǔ)AppDomain中的元數(shù)據(jù)信息,例如基類型、靜態(tài)字段、靜態(tài)方法、接口信息等,不受GC管理,它的生命周期從創(chuàng)建AppDomain開始到卸載AppDomain結(jié)束。此時(shí),托管堆以及其它方面大致是這樣分布的:

→在托管堆上創(chuàng)建對(duì)象
□ 引用類型對(duì)象創(chuàng)建
使用new關(guān)鍵字創(chuàng)建引用類型對(duì)象。
FileStream fs = new FileStream(@"",FileMode.Open);
以上代碼經(jīng)編譯器編譯,在生成的中間IL代碼中實(shí)際上是一個(gè)newobj指令。IL相關(guān)的指令還包括:ldstr指令用于創(chuàng)建string類型對(duì)象,newarr用于分配新的數(shù)組對(duì)象,box指令用于在值類型轉(zhuǎn)換為引用類型時(shí),將值類型字段拷貝到托管堆上。
通過以下代碼來體會(huì)托管堆上創(chuàng)建對(duì)象的大致過程:
public class Employee{PRivate int _id;private Status _status;public Employee(){_id = 1;_status = new Status();}}public class Sales : Employee{public bool _isLive;public bool IsLive(){return _isLive;}public static void Main(){Sales _sales;_sales = new Sales();_sales._isLive = true;Console.WriteLine(_sales.IsLive());}}public class Status{private int _years;private char _level = "A";}
1、執(zhí)行Sales _sales,在線程堆棧上開辟4byte的內(nèi)存空間,用于保存Sales對(duì)象的托管堆地址,此時(shí)為null。
2、_sales = new Sales(),遞歸
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注