天天看點

何為中間語言IL?

一直以來,對于.NET與C#之間的關系我都存在着疑惑,為此,今天專門仔細看了一下以前最容易忽略掉的書本“前言”部分,予以澄清:) 

首先,c#的結構和方法論反映了.NET的基礎方法論,在很多情況下,c#的特定功能取決于.net的功能,依賴于.net基類。通俗一點說,

     (1).net framework 是一個功能豐富的開發平台,可開發,部署和執行分布式應用程式。

(2)c#是一個基于現代面向對象設計方法的語言,它本身隻是一種語言,不是.net的一部分,隻是用它生成面向.net環境的代碼。

     下面,再說兩個知道但不知其是以然的概念,那就是CLR(公共語言運作庫)與

MSIL(微軟中間語言)。.NET Framework的核心是其運作庫的執行環境-----公共語言運作庫(CLR),而在CLR控制下運作的代碼稱為托管代碼,而微軟,又把這些托管代碼命名為MSIL(中間語言)。CLR在執行開發的C#源代碼之前,要先編譯他們。而在.NET中的編譯,一共分為兩個階段:C#代碼-->IL-->平台專用的内部機器碼。這個過程中的第二階段(IL-->平台專用的内部機器碼),是由CLR來執行的。

當然了,使用托管代碼的優點是顯而易見的,主要有以下3個方面:1,平台無關性;2,提高性能;3,語言的互操作性。

C#開發人員應該明白,IL在.NET

Framework中的作用是至關重要的,C#代碼在執行前要編譯為IL,即托管代碼。IL主要有5點優勢:

   (1)面向對象和使用接口:

    .NET接口-----提供一個契約,實作給定接口的類必須提供該接口指定的方法和屬性的實作方式。

    語言的互操作性-----用一種語言編寫的類能直接與另一種語言編寫的類進行通信。所謂通信就是指:用一種語言編寫的類應能繼承另一 種語言編寫的類;一個類應能包含另一個類的執行個體;一個對象應能調用其他語言編寫的另一個對象的方法;對象(或對象的引用)應能在方法之間傳遞;應能調試不同語言之間調用的方法。

(2)值類型和引用類型之間存在着巨大差别:

    值類型和引用類型的概念一定要清楚,IL提供了許多預定義的基本資料類型,歸為值類型和引用類型兩大類:

值類型:變量直接儲存其資料,一般存儲在堆棧中(如果值類型在引用類型中聲明為字段,他們就内聯存儲在堆中)。

引用類型:變量僅儲存位址,對應的資料可以在該位址中找到,引用類型的執行個體總是儲存在一個名為“托管堆”的記憶體區域中。

(3)強資料類型:IL的一個重要方面是它基于強資料類型。所有的資料都清晰地标記為屬于某個特定資料類型。強資料類型雖然會降低性能,但是它可以在以下4個.NET特有的服務中,提供更好的類型安全:

    語言互操作性:CTS(通用類型系統)定義了可以在IL中使用的所有預定義資料類型,它的層次結構反映了IL的單一繼承地面向對象方法。

CLS(公共語言規範)是一個最低标準級,所有的.NET編譯器都必須支援它

    CTS 與 CLS

一起確定語言的互操作性。同時要注意,IL是區分大小寫的。

    垃圾收集:垃圾收集器用來在.NET中進行記憶體管理,特别是它可以恢複正在運作中的應用程式需要的記憶體。

垃圾收集器(GC堆):實質:這是一個程式。

目的:清理記憶體。

  方法:所有動态請求的記憶體都配置設定到堆上(CLR維護它自己的托管堆,供.NET應用程式使用),

當.NET檢測到給定程序的托管堆已滿,需要清理時,就調用垃圾收集器(GC)。GC處

理目前代碼中的所有變量,檢查對存儲在托管堆上的對象的引用,确定哪些對象可以從

代碼中通路(---即哪些對象有引用)。沒有引用的對象就不能在代碼中通路,因而被删除。

之是以在.NET中使用GC器,是因為IL已經用來處理程序,不能引用已有的對象,隻能複制已有的對象,而它又是類型安全的。

    安全性:windows隻提供了基于角色的安全性,而.NET還提供了基于代碼的安全性。

    應用程式域:    

應用程式域是.NET的一個重要技術改進,它主要用于減少運作應用程式的系統開銷,這些應用程式需要與其他程式

分離開來,但同時還需要彼此通信。

在.NET沒有誕生前,可以讓多個對象執行個體共享同一個程序,但是在這種情況下,一旦一個執行個體運作失敗,就有可能

導緻整個程序的運作失敗;或許我們可以把這些執行個體孤立在不同的程序中,但是這樣做會增加相關性能的系統開銷。

孤立代碼的唯一方式就是通過程序來實作:在運作一個新的應用程式時,它會在一個程序環境内運作。windows通過

位址空間來分隔程序。每個程序有4GB的虛拟記憶體來存儲其資料和可執行代碼。然後,windows利用額外的間接方式把這

                    虛拟記憶體映射到實體記憶體或磁盤空間的一個特殊區域中,每個程序都會有不同的映射,即虛拟位址空間塊映射的實體記憶體

之間不能有重疊,也就是說,每個程序都應該對應不同的實體記憶體空間。在一般情況下,任何程序都隻能通過指定虛拟内

存中的一個位址來通路記憶體-------即程序不能直接通路實體記憶體。是以,一個程序不可能通路配置設定給另一個程序的記憶體。

這樣就可以確定任何執行出錯的代碼不會損害其位址空間以外的資料。程序不能共享任何記憶體。

程序不僅是運作代碼的執行個體互相隔離的一種方式,還可以構成配置設定了安全權限和許可的單元。

                         程序對確定安全有很大幫助,但是會犧牲掉性能。許多程序常常一起工作,互相通信。如果使一些元件一起工作,但

不希望性能有所損失,唯一的方法是使用基于DLL的元件-----讓所有的元件都在同一個位址空間中運作(其風險是執行出錯

的元件會影響其它元件)。為了解決這一問題,就出現了應用程式域的概念:應用程式域是分離元件的一種方式,它不會導

                    緻因在程序之間傳遞資料而産生的性能問題。其方法是:把任何一個程序分解到多個應用程式域中,每個應用程式域大緻對

應一個應用程式,執行的每個線程都運作在一個具體的應用程式域中。也就是說,一個程序可以包含多個應用程式域,而線

程又是與應用程式域一一對應的,是以一個程序可以包含多個線程。當在一個程序中運作多個應用程式時,CLR會檢查每個

正在運作的應用程式代碼,以確定這些代碼不偏離它自己的資料區域(應用程式域),保證不發生直接通路其它程序的資料

的情況。

                         澄清幾個對應關系:

(1)程序-------虛拟記憶體------記憶體位址(一一對應)

                         (2)線程-------應用程式域------app(一一對應)

                         (3)多個應用程式app可以共享同一個程序

                         (4)但多個程序不能共享同一塊記憶體空間。

(4)使用異常來處理錯誤:

何為異常?簡單地說,就是代碼的某些領域被看作是異常處理程式例程,每個曆程都能處理某些特殊的錯誤情況,異常結構确定

          發生錯誤情況時,執行程序立即跳到異常處理程式曆程上,處理錯誤情況。

(5)使用特性: 在源代碼中定義特性,特性與對應資料類型和方法放在一起,和反射技術一起使用。

(轉自)