前言 萬事開頭難,很早之前就想寫博客記錄些東西,遲遲未行動,甚是遺憾。原因諸多,大體上無非都是懶、沒意志力等等。這次從自己的讀書筆記開始,興許能夠有所改變。 一、CLR概念 CLR(Common Language Runtime,譯為公共語言運行時)是一個可由多種編程語言使用的“運行時”。CLR的核 ...
前言
萬事開頭難,很早之前就想寫博客記錄些東西,遲遲未行動,甚是遺憾。原因諸多,大體上無非都是懶、沒意志力等等。這次從自己的讀書筆記開始,興許能夠有所改變。
一、CLR概念
CLR(Common Language Runtime,譯為公共語言運行時)是一個可由多種編程語言使用的“運行時”。CLR的核心功能:記憶體管理、程式集載入、安全性、異常處理和線程同步,可由面向CLR的所有語言(C++、C#、VB、F#等等)使用。無論哪種語言,最後通過編譯器的結果都是托管模塊。托管模塊是PE32文件或PE32+文件,都需要CLR才能執行。
組成部分 | 說明 |
PE32或PE32+頭 | 標準windows PE文件頭,如果這個頭是PE32格式,文件能在Windows32位和64位上運行,如果是PE64,文件只能在Windows的64位上運行。這個頭還表示了文件類型,,並包含一個時間標記來指出文件的生成時間。對於只包含IL代碼的模塊,這些信息大部分都會被忽略。如果是包含本機CPU代碼的模塊,這個頭包含本機CPU代碼有關的信息。 |
CLR頭 | 包含使這個模塊成為托管模塊的信息。頭中包含要求的CLR版本,一些標誌(flag),拖過模塊入口方法的元數據token以及模塊的元數據、資源,強模塊、一些標誌以及不太重要的數據項位置/大小 |
元數據 |
每個托管模塊都包含元數據表。分為兩類: 1、描述源代碼中定義的類型和成員。 2、描述源代碼引用的類型和成員。 元數據有諸多用途,例如: 1、元數據錶面了編譯時對原生C/C++和庫文件的需求,因為在實現類型/成員的IL代碼文件中,已包含有關引用類型/成員的全部信息。編譯器直接從托管模塊中讀取元數據。 2、IDE的“智能感知”能夠解析元數據,從而得到一個類型所提供的方法、屬性、事件和欄位。 3、CLR的代碼驗證過程使用元數據確保代碼只執行“類型安全”的操作 4、元數據允許將對象的欄位序列化到記憶體,將其發送給另一臺機器,然後反序列化,在遠程機器上重建對象狀態 5、元數據允許垃圾回收器跟蹤對象生存期,垃圾回收器能判斷任何對象的類型並從元數據知道那個對象中的哪些欄位引用了其他對象 |
IL代碼 | IL代碼也被為托管代碼,因為CLR管理它到底執行。編譯器編譯源代碼時生成的代碼。在運行,CLR將IL編譯成本機CPU指令 |
二、程式集執行過程
IL代碼是與CPU無關的機器語言,當方法執行時,必須把方法的IL轉換成本機CPU命令。下圖是方法的首次調用
在執行Main方法前,CLR會分配一個內部數據結構來管理對引用類型的訪問,在這個內部數據結構項中,存在與類型中方法對應的一個記錄項,這個記錄項含有一個地址,可根據此地址找到方法的具體實現。數據結構初始化時,CLR將每個記錄項都設置成包含在CLR內部的JITComplier。上圖中的WriteLien首次調用時,JITCompiler會被調用,IL將被編譯成CPU指令(JIT,即時編譯)。當WriteLine第二次調用時,會跳過JITCompiler,直接執行CPU中已有的指令。(註:之前有經常遇到過首次調用某類方法明顯比第二次的耗時長,應該與此有關聯,因此有時候需要做預加熱)。 下圖為第二次調用
生成程式集時,有兩種模式:Debug和Release。顯然,根據詞義可知分別是調試模式和發佈模式。兩者主要區別在於兩個C#編譯器開關會影響代碼優化:/optimize和/debug。Debug含有DEBUG常量,以及不優化代碼。Release不包含DEBUG常量,並優化代碼。因此Release模式下的程式集相對而言更小,運行更快。
儘管微軟做了大量的工作來優化,但運行時的二次編譯仍會影響性能,也會分配動態記憶體。但是.NET FrameWork SDK 配套提供了NGen.exe工具,該工具將所有IL代碼編譯成本機代碼,並將這些本機代碼保存到了一個磁碟文件中。NGen.exe能夠:1、提高應用程式的啟動速度;2、減小應用程式的工作集。縱然NGen.exe工具能夠帶來不少好處,卻並非那麼完美,存在如下問題:1、沒有知識產權保護 2、NGen生成的文件可能失去同步 3、交叉的執行時性能。因此,在使用NGen.exe工具時要慎重考慮,除非是啟動耗時的大型客戶端應用程式。
三、Framework類庫
.Net Framework包含Framework類庫(Framework Class Library,FCL)。FCL是一組DLL程式集的同城,其中包含有數千個類型定義。例如:WEB服務、基於HTML的web窗體/MVC應用程式、“富”WIndows GUI應用程式,Windows控制台應用程式,Windows服務,資料庫存儲過程,組件庫等
四、通用類型系統和公共語言規範
為了令一種編程語言寫的代碼能與用另一種編程語言寫的代碼溝通,微軟制定了一個正式的規範來描述類型的定義和行為,這既是“通用類型系統”(Common Type System,CTS)。CTS規定,一個類型可以包含零個以上的成員:欄位、方法、屬性、事件,CTS還指定類型可見性規則以及類型成員的額訪問規則:private、family(protected,派生類型訪問)、assembly(同一個程式可訪問)、public。同時,CTS規定所有類型必須繼承System.Object。CTS還有其他規則,不一一列出。
微軟定義了“公共語言規範”(Common Language Specification,CLS),詳細定義了一個最小功能集,用於不同語言創建的對象可通過COM相互通信,任何支持CLR的編譯器都支持這個功能集。
註:程式集執行過程圖來源自網路