CLR基礎小結

時至今日,CLR基礎部分的學習算是告一段落了。可是由於知識有些龐雜,因此但願在此處作一些總結,以整理所學所得。html

1.CLR的執行模型:編程

簡單來講,這部分所敘述的,就是如何將源代碼生爲一個應用程序,或者生成爲一組能夠從新分發的組件,以及這些組件中包含的類型。最後還解釋了應用程序如何執行。數組

源代碼編譯成託管模塊安全

首先,必需要了解的一個事情就是,CLR的核心功能,以及CLR在託管的時候所作的事情。CLR,全稱Common Language Runtime,公共語言運行時,是一個可由多種編程語言使用的「運行時」。任何面相CLR的語言均可以使用CLR的核心功能。使用支持CLR的語言建立了源代碼文件,而後用對應的編譯器檢查語法和分析源代碼。不管是選擇哪一個編譯器,都是生成託管模塊(好比C#就是:C#源碼經過C#編譯器生成了託管模塊)。所謂託管模塊,就是可移植執行體文件(.exe,.dll,.scr等都是可移植執行體文件)。數據結構

本機代碼編譯器(native code compilers)生成的是面相CPU架構的代碼。而每一個面相CLR的編譯器生成的都是IL(Intermediate Language,中間語言)代碼。IL代碼也被稱爲託管代碼,由CLR管理它的執行。除了生成IL,面相CLR的每一個編譯器還要在每一個託管模塊中生成完整的元數據。元數據是一個數據表的集合,描述了數據的各類引用、定義等。編譯器會同時生成元數據和IL代碼,將之綁在一塊兒,嵌入進最終生成的託管模塊,因此元數據和它描述的IL代碼一直是同步的。架構

編譯器生成的數據,分爲託管模塊(包含託管代碼IL和託管數據集的模塊),和非託管模塊(不須要CLR執行, 在運行時直接操縱非託管數據)。app

託管模塊合併成程序集編程語言

託管模塊並非CLR的工做對象,而程序集(assembly)纔是。程序集,是一個或多個模塊/資源文件的邏輯性分組,也是重用、安全性以及版本控制的最小單元。多個託管模塊和資源文件,經過一些合併程序集所用到的工具,例如C#編譯器(CSC.exe),合併成了程序集(託管模塊合併成了IL和元數據,資源文件仍是資源文件)。函數

加載CLR工具

生成的程序集,能夠是.exe、.dll,最終由CLR管理這些程序集中代碼的執行。換言之,機器必須安裝好.NET Framework。在可執行文件運行時,Windows檢查文件頭(32位or64位);而後檢查頭中嵌入的CPU架構信息。在肯定CPU符合要求後,運行該程序。

爲了運行託管應用程序,Windows檢查EXE文件頭,建立好進程後,會在進程地址空間加載MSCorEE.dll的x86,x64或ARM版本。而後,進程的主線程調用MSCorEE.dll中定義的一個方法。這個方法初始化CLR,加載EXE程序集,再調用入口函數main。

若是是非託管,則應用程序調用LoadLibrary加載託管程序集,Windows會自動加載而且初始化CLR以處理程序集中的代碼。

執行程序集代碼

託管程序集同時包含元數據和IL。IL能訪問操做對象類型,並提供了指令來初始化對象、調用對象上的虛方法以及直接操做數組元素,甚至能夠拋出異常。能夠把IL當作一種面向對象的機器語言。

爲了執行方法,首先必須把IL轉換成本季CPU指令,這是CLR的JIT編譯器的職責。在Main執行以前,CLR會檢測出Main的代碼所引用的全部類型。此時,CLR會分配一個內部數據結構來管理對引用類型的訪問。在這個內部結構中,每一個類型的每一個方法都有一個對應的記錄項(entry,也能夠翻譯成入口),每一個記錄項都有一個地址,根據這個地址能夠找到對應方法的實現。對這個結構初始化的時候,CLR將每一個記錄下都設置成包含在CLR內部的一個未編檔函數,也就是JITCompiler。

Main首次調用函數的時候,JITCompiler被調用。JITCompiler負責將方法的IL代碼編譯成本機指令。由於IL是JIT(just-in-time,即時)編譯的,因此把CLR的這個組件稱爲JIT編譯器。JITCompiler的執行過程以下:

●在負責實現類型的程序集的元數據中查找被調用的方法

●從元數據中獲取該方法的IL

●分配內存

●將IL編譯成本機CPU指令,而後將這些本機代碼存儲到分配的內存中

●在Type表中修改與方法對應的條目,使其指向分配的內存塊

●跳轉到內存塊中的本機代碼

在Main第二次調用的時候,由於已經對方法進行了驗證和編譯,因此會跳過JITCompiler直接執行內存塊的代碼。也正因如此,才使得僅在首次調用的時候纔會發生性能損失。

將IL編譯成本機CPU指令的時候,有一個驗證的過程。這個過程會檢查IL代碼,肯定代碼的安全性。

Microsoft C#編譯器默認生成安全的代碼,可是也容許開發人員寫不安全的代碼。所謂不安全的代碼,就是代碼能夠直接操做內存地址。使用的時候,不安全代碼的方法須要用unsafe作標記。而且在編譯的時候,須要使用/unsafe開關來編譯源代碼。

NGen.exe

NGen.exe工具,能夠在應用程序安裝到用戶的計算機上時,將IL代碼編譯成本機代碼。由於代碼在安裝的時候已經編譯好,因此一般不須要在運行的時候編譯IL代碼。因此,NGen.exe的主要做用是:提升應用程序的啓動速度,以及減小應用程序的工做集。

每當CLR加載程序集文件,都會檢查是否存在一個對應的、由NGen生成的本機文件。若是找不到本機文件,CLR就和往常同樣對IL代碼進行JIT編譯。若是有對應的本機文件,CLR就直接使用本機文件中編譯好的代碼,不須要在運行時編譯。

可是,NGen生成的文件也會有以下問題:沒有知識產權保護、生成的文件可能丟失同步、較差的執行性能。因此,服務端的應用程序,NGen的做用就不甚明顯。而在客戶端的程序,就能夠提升啓動速度、縮小工做集等。

本章的其餘內容爲後續章節的概述,不涉及很複雜的理解,因此就不在此作過多贅述了。


2.生成、打包、部署和管理應用程序及類型:

在本章,將重點解釋如何生成僅供本身的應用程序使用的程序集

將類型生成到模塊中

Program.cs

 1 using System;
 2 
 3 namespace Project_1
 4 {
 5     public class Program
 6     {
 7         public static void Main(string[] args)
 8         {
 9             System.Console.WriteLine("HaHa");
10        }
11     }
12 }

執行命令,生成可執行文件Program.exe:csc.exe /out:Program.exe /t:exe /r:MscorLib.dll Program.cs

能夠簡化爲:csc.exe Program.cs

響應文件,是包含一組編譯器命令行開關的文本文件。執行CSC.exe時,編譯器打開響應文件,並使用其中包含的全部開關。此外,編譯器還會查找CSC.rsp文件。該文件引用了和CSC.exe相關的全部程序集。

元數據

元數據是由三種表構成的二進制數據塊:定義表,引用表和清單表。編譯源碼的時候,任何定義的東西都致使在某個表中建立一個記錄項。此外,編譯器還會檢測源碼引用的類型、字段、方法、屬性和事件,並建立相應的元數據表記錄項。在建立的元數據表中包含一組引用表,包含了引用的內容。

要查看元數據表,可使用IL反彙編工具ILDasm.exe:ILDasm Program.exe

將模塊合併成程序集

 這部份內容涉及到不少實際操做,具體內容就不作贅述了,詳情請見https://www.cnblogs.com/renzhoushan/p/10366289.html。這裏只簡述一下爲何這樣作。

之因此要引入「程序集」的概念,就是爲了可重用類型的邏輯表示與物理表示能夠分開。之因此使用多文件程序集,主要用以下三點理由:

●不一樣類型用不一樣的文件,使得文件能夠以「增量」方式下載;

●能夠在程序集中添加資源或數據文件;

●程序集包含的各個類型能夠用不一樣的編程語言來實現。

程序集版本資源信息和語言文化

 在生成PE文件程序集時,還會在PE文件中嵌入標準的Win32版本資源,能夠查看文件屬性來檢查該資源的版本號。

 除了版本號,程序集還將語言文化做爲身份標識的一部分。若是程序包含語言文化特有的資源,Microsoft會建議專門建立一個程序集來包含代碼和應用程序的默認資源。生成該程序集時不要指定具體的語言文化。其餘程序集經過引用該程序及來操縱它公開的類型。而後,建立一個或多個單獨的程序集,只在其中包含語言文化特有的資源:不包含任何代碼。標記了語言文化的程序集,被稱爲附屬程序集。爲附屬程序集指定的語言文化應準確反映程序集中的資源的語言文化。想要支持的每種語言文化都要建立單獨的附屬程序集。

簡單的應用程序部署:私有部署的程序集

 不一樣的程序集打包方式不一樣。例如,Windows Store應用在打包的時候,VS會將全部必要的程序集打包成一個.appx文件。用戶在安裝的時候,其中包含的全部程序集都進入一個目錄,CLR從該目錄加載程序集,Windows則在用戶的「開始」添加對應的程序磁貼。若是是其餘用戶安裝一樣的.appx,則會使用以前安裝好的,只是添加了一個磁貼。在卸載的時候,也是先刪除磁貼。若是沒有其餘用戶安裝該應用,就刪除目錄和其中全部的程序集。

在應用程序基目錄或者子目錄部署的程序集稱爲私有部署的程序集,這是由於程序集文件不和其餘任何程序共享。之因此能實現簡單的安裝/移動/卸載,是由於每一個程序及都用元數據註明了本身引用的程序集,不須要註冊表設置。

簡單管理控制/配置 

 爲了實現對應用程序的管理控制,能夠在應用程序目錄放入一個配置文件。發佈者能夠建立並打包該文件。安裝程序會將配置文件安裝到應用程序的基目錄。此外,計算機管理員或最終用戶也能建立或修改該文件,CLR會解析文件內容來更改程序集文件的定位和加載策略。

3.共享程序集和強命名程序集:

相關文章
相關標籤/搜索