程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> 帶著問題讀CLR via C#(筆記一)CLR的執行模型

帶著問題讀CLR via C#(筆記一)CLR的執行模型

編輯:C#基礎知識

Q1: 什麼是CLR?

A1: CLR (Common Language Runtime) 是一個可以由多種編程語言使用的“運行時”。

Q2: CLR的核心功能有哪些?

A2: 1)內存管理;2)程序集加載;3)安全性;4)異常處理;5)線程同步

Q3: CLR與使用的編程語言有關嗎?

A3: 無關。只要編譯器是面向CLR的就行。

Q4: 選用不同編程語言經過面向CLR的編譯器編譯後生成的結果相同嗎?

A4: 相同。無論選擇什麼語言,相應的編譯器變異的結果都是一個托管模塊,即一個標准的32位PE (Portable Executable) 32文件或64位PE32+文件。它們都需要CLR才能執行。

Q5: 托管模塊的組成部分是什麼,它們的作用分別是什麼?

A5: 1)PE32或PE32+頭;2)CLR頭;3)元數據;4)中間語言

PE32頭:1)標識了文件類型(GUI, CUI, DLL);2)包含一個文件生成時間的時間標記;3)包含與本地CPU代碼有關的信息(在該模塊包含CPU代碼的情況下)。

CLR頭:1)包含需要的CLR版本;2)托管模塊入口方法的MethodDef元數據標記;3)模塊的元數據,資源,強名稱,一些標記以及不太重要的數據項的位置及大小。

元數據:1)包含描述源代碼中定義的類型及成員的元數據表;2)包含描述源代碼中引用的類型和成員。

中間語言:編譯器編譯源代碼生成的代碼,運行時會被CLR編譯為本地CPU指令。

Q6: 什麼是程序集?

A6: 程序集是一個抽象的概念,它是一個或多個模塊/資源文件的邏輯分組,也是重用,安全性以及版本控制的最小單元。 生成的程序集既可以是一個可執行文件(exe)也可以是一個DLL.

Q7: 托管模塊和程序集之間的關系是什麼?

A7: 默認情況下,編譯器實際會把生成的托管模塊轉換為程序集,程序集的清單中會指明該程序集僅有一個文件構成。如果項目中只有一個托管模塊,沒有資源文件或數據文件,那麼程序集就是托管模塊。如果想將多個文件合並到一個程序集,則需要使用其他工具來實現。

Q8: 方法執行的過程是什麼?首次執行和之後執行有區別嗎?

A8: 執行一個方法需要將程序集中的IL轉換為本地CPU指令,這項工作由CLR的JIT(即時)編譯器來完成。用如下例子講解:

代碼如下:

static void Main()
{
    Console.WriteLine("Hello");
    Console.WriteLine("GoodBye");
}

分析准備階段:

1)      CLR檢測Main代碼引用的所有類型,此例中為Console類型;

2)      CLR分配一個內部數據結構,用於管理對引用的類型(即Console類型)的訪問。Console類型中的所有方法在這個內部結構中都有一個入口, 通過該入口可以找到方法的具體實現;對該內部結構初始化時,CLR將每個方法的入口都設置成指向JITCompiler函數(CLR內部未文檔化的一個函數);

執行階段:

1)      Main方法中首次調用WriteLine方法時,JITCompiler函數會被調用,這個函數知道調用的是哪個方法(WriteLine),以及什麼類型(Console)調用了該方法;

2)      JITCompiler在定義了該類型的程序集元數據中查找該方法(WriteLine)的IL,並對IL進行驗證,若無誤,則將該IL編譯為本地CPU指令;

3)      將本地CPU指令保存至一個動態分配的內存塊;

4)      JITCompiler返回最初為Console類型創建的內部結構,找到WriteLine方法的入口,並將之前設置的指向JITCompiler的引用改為指向保存本地CPU指令的內存塊;

5)      JITCompiler回到保存本地CPU指令的內存塊,並執行該指令。

當Console.WriteLine("Hello")執行結束後,繼續執行下一行代碼Console.WriteLine("Goodbye"),由於Console.WriteLine方法已經編譯為本地CPU指令了,就會跳過JITCompiler函數的繁瑣操作,直接執行本地CPU代碼。但當應用程序終止後再次啟動運行這段代碼,JIT編譯器必須重新將IL編譯為本地CPU指令,因為之前是保存在內存塊中的,程序終止後內存塊會被清空。

Q9: IL有什麼優勢?

A9: IL可以提高應用程序的健壯性和安全性。在將IL編譯為本地CPU指令時,CLR會執行驗證過程,確保代碼做的一切都是安全的(參數數量是否正確,參數類型是否正確,返回值是否被正確使用等等)。

Q10: 比較CLR, CTS和CLS.

A10: CLR是一個可以由多種編程語言使用的“運行時”, 它是圍繞類型展開的,類型為應用程序和其他類型公開了功能,通過類型,可以用一種編程語言系的代碼和另一種編程語言寫的代碼進行溝通,而CTS則是一個”通用類型系統”,它描述了類型的定義和行為。而由於CLR允許一種語言使用另一種語言定義的類型,但各種編程語言存在極大的區別,例如有些語言區分大小寫而有些語言不區分,CLS是一個 ”公共語言規范”, 它定義了一個最小功能集,用一種語言定義了一種類型時,若想要其他語言可以使用該類型,就不要在該類型的public和protected成員中使用超出CLS的功能。每種編程語言都提供了CLR/CTS的一個子集以及CLS的一個超集。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved