Chapter1 CLR的执行模式
1.1將源代碼編譯成托管模塊
一、托管模塊的各個組成部分
1.PE32或PE32+頭,標準的WindowsPE文件頭,如果這個頭使用的是PE32格式,文件只能在32或64位系統(tǒng)上運行,如果頭是PE32+格式只能在64位系統(tǒng)上運行
2.CLR頭
3.元數(shù)據(jù),一組數(shù)據(jù)表,主要包含兩種表:①描述源代碼中定義的類型和成員②描述源代碼引用的類型和成員。
4.IL(中間語言)代碼,編譯器編譯源代碼時生成的代碼,在運行時,CLR將IL編譯成本地CPU指令。
二、元數(shù)據(jù)多種用途
1.編譯時,元數(shù)據(jù)消除了對本地C/C++頭和庫文件的需求(在IL代碼文件中,已經(jīng)包含和引用的類型/成員有關(guān)的全部信息,編譯器可以直接從托管模塊讀取元數(shù)據(jù))。
2.使用元數(shù)據(jù)幫你寫代碼————智能感知。
3.CLR的代碼驗證過程使用元數(shù)據(jù)確保代碼只執(zhí)行“類型安全”的操作。
4.序列化-反序列化。
5.允許GC跟蹤對象的生存期。
1.2將托管模塊合并成程序集
程序集:一個或多個模塊/資源文件的邏輯性分組,其次,是重用、安全性以及版本控制的最小單元。它可以是一個可執(zhí)行應(yīng)用程序、也可以是個DLL
1.3加載公共語言運行時
CLR管理程序集代碼的執(zhí)行,所以必須安裝.Net Framework
要知道是否安裝.Net Framework,只需檢查%SystemRoot%\System32目錄中的MSCorEE.dll文件是否存在。
.Net Framework SDK提供了一個名為CLRVer.exe的命令執(zhí)行程序,它能列出已經(jīng)安裝了的所有CLR版本
/platform開關(guān)選項對生成的模塊的影響以及在運行時的影響
1.4執(zhí)行程序集的代碼
托管程序集同時包含元數(shù)據(jù)和IL,IL是與CPU無關(guān)的機器語言,但比大多數(shù)CPU機器語言要高級,還可以創(chuàng)建初始化對象、調(diào)用對象上的虛方法以及直接操作數(shù)組元素、捕獲異常并拋出。綜上所述可將IL視為一種面向?qū)ο蟮臋C器語言,IL可有ILAsm.exe的IL匯編器和ILDasm.exe的IL反匯編。 為了執(zhí)行一個方法,首先必須把它的IL轉(zhuǎn)換成本地CPU指令,這是CLR的JIT編譯器的職責。
一個方法首次調(diào)用時發(fā)生的事情
第二次調(diào)用時發(fā)生的事情
Main函數(shù)第二次調(diào)用WriteLine時由于已對WriteLine的代碼進行了驗證和編譯,所以會直接執(zhí)行內(nèi)存塊中的代碼,完全跳過JITCompiler函數(shù)(一旦進程終止,編譯好的代碼將被丟棄)。
還要注意的是,CLR的JIT會對本地代碼進行優(yōu)化,可能會花費一些時間,但性能更出色
有兩個C#編譯器的開關(guān)會影響代碼的優(yōu)化:/optimize和/debug
| 編譯器開關(guān)設(shè)置 | C#IL代碼質(zhì)量 | JIT本地代碼質(zhì)量 |
| /optimize-/debug-(默認) | 未優(yōu)化 | 有優(yōu)化 |
| /optimize-/debug(+/full/pdbonly) | 未優(yōu)化 | 未優(yōu)化 |
| /optimize+/debug(-/+/full/pdbonly) | 有優(yōu)化 | 未優(yōu)化 |
使用/optimize-在C#編譯器生成的未優(yōu)化的IL代碼中,將包含許多NOP(no-operation,空操作)指令,如果在調(diào)試期間,還可以在控制流程(如for,while,do,if,else,try,catch和finally語句塊)上設(shè)置斷點,使代碼更易于調(diào)試,相反如果優(yōu)化IL代碼,則不能在上述流程中調(diào)試。 另外只有在指定/debug(+/full/pdbonly)開關(guān)的前提下編譯器才會生成Program Database(PDB)文件
在Visual Studio中項目的
Debug(調(diào)試)配置對應(yīng)的是/optimize-和/debug:full開關(guān)。
Release(發(fā)布)配置對應(yīng)的是/optimize+和/debug:pdbonly開關(guān)
1.4.1 IL和驗證
IL是基于棧的,在編譯IL到本地指令的過程中,CLR會有一個驗證的過程(包括方法正確數(shù)量的參數(shù),正確的參數(shù)類型,返回值正確的使用,都有返回語句),在托管模塊的元數(shù)據(jù)中包含了所有方法和類型信息。
1.4.2 不安全的代碼
不安全代碼允許直接操作內(nèi)存地址,并可操作這些地址處的字節(jié)(通常在與非托管代碼進行交互時,或提高對效率極高的算法時才需要這樣做)
C#采用unsafe關(guān)鍵字,要求使用/unsafe編譯器開關(guān)來編譯
MS提供了一個PEVerify.exe的程序來檢查程序集的所有方法是否采用不安全代碼
1.5 本地代碼生成器:NGen.exe
可以在一個應(yīng)用程序安裝到用戶計算機上時,將IL代碼編譯成本地代碼,由于代碼在安裝時已經(jīng)編譯好了,所以CLR的JIT無需編譯IL代碼,提升性能
兩個應(yīng)用場景:
加快應(yīng)用程序的啟動速度:運行時不需要花時間來編譯
減小應(yīng)用程序的工作集
NGen生成的文件存在一下問題:
沒有只是產(chǎn)權(quán)保護
NGen生成的文件可能失去同步(并不是一勞永逸很容易失效)
較差的執(zhí)行時性能
1.6 Framework 類庫
利用這些程序集可以創(chuàng)建一部分應(yīng)用
1.Webservice
2.WebForm
3.Windows應(yīng)用程序
4.RIA(Silverlight)
5.Windows控制臺應(yīng)用程序
6.Windows服務(wù)
7.數(shù)據(jù)庫存儲過程
8.組件庫
1.7 通用類型系統(tǒng)(CTS)
基本成員
Field、Method、Property、Event
成員訪問修飾符(C#)
private:只能有同一個class類型中的其他成員訪問
protected:可有派生類型訪問,不管那些類型是否在同一個程序集
internal:成員可由同一個程序集的任何代碼訪問
protected internal:成員可有任何程序集中的派生類型訪問,也可由同一程序集的任何類型訪問
public:任何程序集的任何類型訪問
理解“代碼的語言”和“代碼的行為”:
使用不同的語言,用于定義類型的語法也不同,無論使用哪一種語言,類型的行為都是完全一致的,因為最終是由CLR的CTS來定義類型的行為。
eg:CTS規(guī)定類型只能單繼承,但C++語言允許多繼承,CTS既不能接受、也不能操作這樣的類型,所以就會報錯。
CTS另一條規(guī)則:所有類型必須從預(yù)定義的System.Object類型繼承,System.Object類型允許做下面事情:
1.比較兩個實例的相等性
2.獲取實例的哈希碼
3.查詢一個實例的真正類型
4.執(zhí)行實例的淺拷貝
5.獲取實例對象的當前狀態(tài)的一個字符串表示
1.8 公共語言規(guī)范(CLS)
CLR集成了所有語言,允許在一種語言中使用由另一種語言創(chuàng)建的對象
C#中特性:[assembly:CLSCompliant(true)]
1.9 與非托管代碼的互操作性
1.托管代碼能調(diào)用DLL中的非托管函數(shù)
2.托管代碼可以使用現(xiàn)有的COM組件(服務(wù)器)
3.非托管代碼可以使用托管類型(服務(wù)器)
總結(jié):首先編譯器把源代碼->托管模塊(包含PE32頭、CLR頭、元數(shù)據(jù)、IL代碼)
由于CLR是不和模塊們一塊工作的,它只愛程序集(assembly)
編譯器不得不把托管模塊們合并成->程序集
于是CLR和程序集在一起了,光在一起不行還是得干活的
CLR有以小弟叫JITCompiler,它對程序集中的IL轉(zhuǎn)換成本地的CPU指令存到內(nèi)存中
轉(zhuǎn)載于:https://www.cnblogs.com/hailiang2013/archive/2013/01/07/2849228.html
總結(jié)
以上是生活随笔為你收集整理的Chapter1 CLR的执行模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三章:Creating Utiliti
- 下一篇: 修改了一下voddown.py