C#基礎知識之托管代碼和非托管代碼


什么是托管代碼(managed code)?

  托管代碼(Managed Code)就是中間語言(IL)代碼,在公共語言運行庫(CLR)中運行。編譯器把代碼編譯成中間語言,當方法被調用時,CLR把具體的方法編譯成適合本地計算機運行的機器碼,並且將編譯好的機器碼緩存起來,以備下次調用使用。隨着程序集的運行,CLR提供各種服務:內存管理,安全管理,線程管理,垃圾回收,類型檢查等等。

  托管代碼是一microsoft的中間語言(IL),他主要的作用是在.NET FRAMEWORK的公共語言運行庫(CLR)執行代碼前去編譯源代碼,也就是說托管代碼充當着翻譯的作用,源代碼在運行時分為兩個階段:      

1.源代碼編譯為托管代碼,(所以源代碼可以有很多種,如VB,C#,J#)      

2.托管代碼編譯為microsoft的平台專用語言。

  編譯器把代碼編譯成中間語言(IL),而不是能直接在你的電腦上運行的機器碼。中間語言被封裝在一個叫程序集(assembly)的文件中,程序集中包含了描述你所創建的類,方法和屬性(例如安全需求)的所有元數據。你可以拷貝這個程序集到另一台服務器上部署它。

  托管代碼在公共語言運行庫(CLR)中運行。這個運行庫給你的運行代碼提供各種各樣的服務,通常來說,他會加載和驗證程序集,以此來保證中間語言的正確性。當某些方法被調用的時候,運行庫把具體的方法編譯成適合本地計算機運行的機械碼,然后會把編譯好的機械碼緩存起來,以備下次調用。(這就是即時編譯)隨着程序集的運行,運行庫會持續地提供各種服務,例如自動垃圾回收、運行庫類型檢查和安全支持等。這些服務幫助提供獨立於平台和語言的、統一的托管代碼應用程序行為。

  Visual Basic .NET和C#只能產生托管代碼。如果你用這類語言寫程序,那么所產生的代碼就是托管代碼。如果你願意,Visual C++ .NET可以生成托管代碼。當你創建一個項目的時候,選擇名字是以.Managed開頭的項目類型。例如.Managed C++ application。

什么是非托管代碼(unmanaged code)?  

  非托管代碼,直接編譯成目標計算機碼,在公共語言運行庫環境的外部,由操作系統直接執行的代碼,代碼必須自己提供垃圾回收,類型檢查,安全支持等服務。如需要內存管理等服務,必須顯示調用操作系統的接口,通常調用Windows SDK所提供的API來實現內存管理。

  當項目選擇名字以MFC,ATL,Win32開頭的項目類型,那么這個項目所產生的就是非托管程序。

  非托管代碼就是在Visual Studio .NET 2002發布之前所創建的代碼。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,連那些依然殘存在你的硬盤中、擁有超過15年歷史的陳舊C編譯器所產生的代碼都是非托管代碼。托管代碼直接編譯成目標計算機的機械碼,這些代碼只能運行在編譯出它們的計算機上,或者是其它相同處理器或者幾乎一樣處理器的計算機上。非托管代碼不能享受一些運行庫所提供的服務,例如安全和內存管理等。如果非托管代碼需要進行內存管理等服務,就必須顯式地調用操作系統的接口,通常來說,它們會調用Windows SDK所提供的API來實現。就最近的情況來看,非托管程序會通過COM接口來獲取操作系統服務。

  跟Visual Studio平台的其他編程語言不一樣,Visual C++可以創建非托管程序。當你創建一個項目,並且選擇名字以M FC,ATL或者Win32開頭的項目類型,那么這個項目所產生的就是非托管程序。

托管代碼和非托管代碼的區別:

  1、托管代碼是一種中間語言,運行在CLR上;非托管代碼被編譯為機器碼,運行在機器上。

  2、托管代碼獨立於平台和語言,能更好的實現不同語言平台之間的兼容;非托管代碼依賴於平台和語言。

  3、托管代碼可享受CLR提供的服務(如安全檢測、垃圾回收等),不需要自己完成這些操作;非托管代碼需要自己提供安全檢測、垃圾回收等操作。

     

托管代碼與非托管代碼的性能比較      

基本上每個人都知道的是,所有.Net語言都將被編譯成為一個叫做IL匯編的中間語言。但是計算機是如何執行這個中間代碼的,卻是很多人不知道,甚至理解錯誤了的。JIT是.NET程序運行的重要部件之一,全稱是即時編譯器。很多人都以為JIT其實就是跟Java VM差不多的東西,是一個Interpreter,在運行時讀取IL匯編代碼,然后模擬成x86代碼(也就是俗稱的虛擬機)。但是事實上,.NET使用的是更為高級的技術。 .Net程序被加載入內存以后,當某段IL代碼被第一次運行的時候,JIT編譯器就會將這段IL代碼,全部編譯成本地代碼,然后再執行。這也就是為什么.NET程序第一次運行都啟動很慢的原因! 隨.NET庫,微軟還附帶了一個工具,可以事先將.NET程序所有的IL代碼都編譯成本地代碼並保存在緩存區中,這樣一來,這個程序就跟c++編譯的一模一樣了,沒有任何區別,運行時也可以脫離JIT了(這里不要混淆了,這里不是說可以脫離.NET庫,而是說不需要在進行即時編譯這個過程了)。所以,請不要將.NET和Java混為一談,兩個的運行效率根本不是一個等級的!

  JIT的優化指的是可以針對本地CPU,在編譯時進行優化。傳統程序在編譯時,為了保證兼容性,通常使用最通用的指令集(比如古老的386指令集)來編譯。而JIT知道CPU的具體類型,可以充分利用這些附加指令集進行編譯,這樣的性能提升是很可觀的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM