目前在看CLR via C#,把總結的記下來,索性就把他寫成一個系列吧。
1.【.Net基礎一】 類型、對象、線程棧、託管堆運行時的相互關係
2.【.Net基礎二】淺談引用類型、值類型和裝箱、拆箱html
接下來的會講到方法的調用,這裏先講下JIT編譯器。以CLR書中的代碼爲例(手打...)。
以Main方法爲例:數據庫
static void Main(){ Console.WriteLine("Hello"); Console.WriteLine("XiaoCong"); }
對結構進行初始化時,會把記錄項指向JITCompiler函數。
數據結構
當第二次執行wirteLine時,因爲第一次已經進行了驗證和編譯,因此跳過JIT函數,直接執行內存塊中的代碼。ide
寫博客效率好低(Orz)。。。函數
下文講到對象和類型對象要注意區分編碼
首先進程運行時,會在託管堆上建立一個System.Type的類型對象(文章後邊解釋)。而後進程中的線程建立時會分配一個1MB大小的棧。
線程
先上一段代碼(在書中代碼基礎上進行修改)3d
internal class Employee{ public Int32 GetYearsEmployed(){...} //非虛實例方法(實例方法) public virtual String GenProgressReprot(){...}//虛實例方法(虛方法) public static Employee LookUp(String name){...}//靜態方法 } internal sealed class Manager:Employee{ public override String GenProgressReport(){...}//重寫方法(虛方法) } void M1(){ String name="XiaoCong"; M2(name); ... return } void M2(String str){ Employee e; Int32 year; e = new Manager(); e = Employee.LookUp("ZhangSan"); year = e.GetYearsEmployed(); e.GenProgressReport(); }
序幕代碼:進行一些初始化變量操做(初始化null或0)
結尾代碼:負責方法完成以後對其進行清理操做。
調用一個方法時,還會將【返回地址】壓入棧,方法在執行結束以後要返回這個位置。
指針
e = new Manager();
這會在託管堆中建立一個Manager類型對象的一個實例。即Manager對象(注意區分和類型對象的區別)。
該對象也包含類型對象指針和同步塊索引。還包含必要的字節來容納Manager類型定義的全部實例數據字段(包括基類字段)。
CLR會自動初始化內容類型對象指針,讓它引用Manger類型對象。也會初始化同步塊索引,並將對象的全部實例字段設爲Null或0,而後調用類型構造器(修改實例字段數據)。
new 操做符返回Manager對象的內存地址,並將地址保存在變量e中。
code
e = Employee.LookUp("ZhangSan");
調用靜態方法時,CLR會定位到靜態方法的類型對象的類型對象(Employee類型對象)。而後找到對應的方法表中的記錄項,對方法進行JIT編譯(第一次執行該方法),再調用JIT生成的CPU指令。假設該方法到數據庫中查找ZhangSan,而後返回一個全新的Manager對象,LookUp方法就會在堆上構造一個全新的Manager對象,用ZhangSan的數據庫信息初始化它。而後返回該對象的地址保存在變量e中。而後舊的Manager對象會等待垃圾回收器進行回收釋放。
year = e.GetYearsEmployed();
調用實例方法,JIT編譯器會找到發出調用變量的類型(這裏是e的類型Employee)的類型對象(Employee類型對象)。而後JIT查找記錄項,對方法進行編譯,執行CPU指令。
若是Employee類型沒有定義那個方法,則會沿着基類一直尋找,直到Object類型。之因此能沿途查找,是由於每一個類型對象都有一個字段引用了它的基類型。
假設該方法返回5,則year就會爲5。
e.GenProgressReport();
調用虛方法,JIT要在方法中生成一些額外代碼。這些代碼首先檢查發出調用的變量,而後跟隨地址找到發出調用的對象(這裏是新的Manager對象)。接着代碼對象內部「類型對象指針」,而後在類型對象(Manager類型對象)方法表中查找記錄項,編譯成成CPU代碼。
若是LookUp方法發現的是一個Employee類型,這裏執行的就是Employee類型的GenProgressReport方法。
基礎太差,我的理解不知道是否有錯誤,有錯誤請指正,謝謝。
看書不易,寫博客也不易,該睡了。。。( ╯□╰ )