斗地主你什么时候才会托管?(.NET中的托管于非托管)
文章部分引自《.NET4.0面向對象編程漫談(基礎篇)》第1章.NET面向對象編程基礎(作者:金旭亮)
?
無意間看到一位四五歲左右小朋友在玩斗地主,總開始到結束,她一直都在使用“提示”(托管)出牌,你猜的沒錯,到最后她贏了。
那么你什么時候才會使用“托管”呢?“我想繼續游戲,但是牌太爛了,索性托管吧或者我想玩,但是我會兒剛好有事需要處理”
?
實際上,我們在選擇了.NET Framework平臺后,就該選擇使用什么語言了,但是每種語言都有自己的優缺點,例如,在非托管C/C++可對系統(Windows)進行一些很低的控制,可以按照自己的想法管理內存,控制線程,當然這些事情你如果不想關心,完全可以丟給CLR去處理,它可以幫你處理的核心功能,比如內存管理,程序集加載,安全性,異常處理,線程同步,當然這些babyservice的待遇只能給托管的代碼使用。
?
非托管應用程序的執行過程
首先看一下Windows操作系統執行一個普通程序(即非托管程序)的基本過程。
軟件工程師寫的程序,經過編譯器轉為機器指令后,一般以文件的方式保存在外部存儲器中,當CPU執行程序時,要先把外部存儲器中的程序指令代碼讀到內存。
內存被分成很多塊(稱為"內存單元"),每個內存單元都有一個唯一的地址,指令就存放在以某個特定的地址開始的內存區域(即"若干個內存單元的集合")中。保存要執行的第一條機器指令的那個內存單元就是程序的"入口點(Entry Point)"。
當程序執行時,CPU從入口點取出第一條指令,開始執行,然后再取第二條,依次類推……
把一個程序從外部存儲器上裝入內存執行是一個復雜的過程,這個功能由操作系統實現,開發具體應用程序的軟件工程師通常不需要手動去寫這部分代碼。
由此可知,程序的運行必須依賴于操作系統(如Windows),而且編譯器生成的程序文件包含的是僅適用于特定CPU架構的機器指令,由于不同CPU架構的機器指令集不同,所以,這個可執行程序無法不加修改地在擁有不同CPU架構的計算機上運行。
以這種方式生成的機器指令代碼稱為"非托管代碼(Unmanaged Code)"。非托管代碼不僅不能在不同CPU架構的計算機上執行,而且通常在不同的操作系統下也不能執行,比如一個Windows應用程序就無法直接在 Linux下運行,反之亦然,這說明非托管代碼的可移植性是受到較大限制的。
如果需要在擁有不同CPU架構的計算機和多種多樣的操作系統上實現同一功能,必須針對每種操作系統和CPU架構編寫特定的代碼,這明顯是一種重復且低效的勞動。
程序能不能只寫一次,到處運行?
完全可以的,這就是 "跨平臺"的設計思想(Java就是一個典范)。.NET也采用了這種設計思想,而且走得更遠,.NET在架構設計上不僅允許.NET應用程序在各種操作 系統和CPU架構上運行,而且允許在同一個程序中混合使用由不同的編程語言開發出來的軟件組件,.NET的這一特性被稱為"跨語言"。
要支持跨平臺這一特性,軟件工程師編寫的程序經過編譯器生成的結果就不能是依賴于操作系統和特定CPU架構的機器指令了,而必須是一種"中立"的、 在各種操作系統和CPU架構上都能執行的代碼,這種代碼Java稱為"Byte Code(字節碼)",.NET稱之為"IL(中間語言)"。
但程序最終還是要靠CPU執行的,所以,Java的字節碼和.NET的IL代碼仍然需要最終被翻譯成本地CPU能執行的機器指令,這部分功能由一個運行在特定操作系統之上的軟件系統來完成,這個軟件系統被稱之為"虛擬機(Virtual Machine,VM)"。
| ? |
| 圖1-9? 托管代碼運行原理 |
只需為每種操作系統和CPU架構提供一個虛擬機,就可以讓同樣一個應用程序不加修改地"跑"在運行不同操作系統、擁有不同CPU架構的計算機上。
這種運行在虛擬機之上的代碼,被稱為"托管代碼(Managed Code)",其原理如圖1-9所示。
使用C#編譯器csc.exe編譯生成的可執行程序實際包含的只是IL指令代碼,這是一種托管代碼,只能運行在.NET虛擬機之上。所以,如果某臺 計算機上沒有安裝.NET Framework,就意味著圖 1 9的"虛擬機"一層不存在,.NET應用程序就無法執行。對于非Windows的操作系統,只要上面有.NET虛擬機,就可以運行.NET程序,通常不需 要修改.NET應用程序源代碼再重新編譯。
一個應用程序可以只采用托管代碼來構建,完全依賴CLR以及.NET Framework類庫,也可以混合使用托管代碼和非托管代碼進行構建。托管代碼調用非托管代碼的技術,在.NET中被稱為"平臺調用(Platform Invoke)"(見圖1-10)。
| ? |
| (點擊查看大圖)圖1-10? 托管代碼與非托管代碼 |
托管代碼執行的過程
.NET下可直接運行的.exe文件包含的是IL指令。IL是微軟和第三方編譯器供應商磋商而創建的"虛"機器語言,之所以說它是"虛"的,是說它 獨立于特定架構的CPU,并且引入了許多具有面向對象特征的指令,與傳統的直接面向硬件的匯編指令有著很大的不同,可以看成是"面向對象的"匯編指令。
由于IL指令獨立于特定架構的CPU,因此它必須經過一個"翻譯"過程,轉換成本地CPU支持的機器指令,才可以最終執行。這個"翻譯者"就是"JIT編譯器(Just-In-Time Complier)",請看圖1-11。
如圖1-11所示,程序源代碼經語言編譯器生成程序集,其中包含IL指令代碼。當程序運行時,"類裝載器(Class Loader)"從外部存儲器中將IL指令讀入內存,再經過JIT編譯器動態地編譯為本地CPU指令代碼執行。在進行即時編譯的過程中,CLR同時檢查這 些IL指令是否違反了一些安全規則,必要時CLR會停止編譯并中斷程序的執行。
| ? |
| (點擊查看大圖)圖1-11? 托管代碼的執行過程 |
上述即時編譯和代碼驗證的過程僅僅只是在第一次調用某個方法時發生。CLR會將編譯好的本地代碼緩存起來,第二次調用時就直接調用緩存中的本地代碼,從而避免了再次編譯所帶來的性能損失。
當然這樣的性能損失可以通過升級硬件設備來減少(避免)。
?
轉載于:https://www.cnblogs.com/tymonyang/p/4455508.html
總結
以上是生活随笔為你收集整理的斗地主你什么时候才会托管?(.NET中的托管于非托管)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 解决时间相减问题
- 下一篇: 如何构建ASP.NET MVC4JQue