程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【C#進階系列】01 CLR的執行模型——一個Hello World的故事,

【C#進階系列】01 CLR的執行模型——一個Hello World的故事,

編輯:C#入門知識

【C#進階系列】01 CLR的執行模型——一個Hello World的故事,


好吧,廢話少說,先上一章Hello World圖:

我們有了一個Hello world程序,如此之簡單,再加上我今天沒有用漢字編程o(>﹏<)o,所以一切很簡單明了。

故事開始:

編譯:

一個程序寫完肯定要編譯,以前什麼C啊什麼的都是編譯成本機的CPU指令,但是我們的C#不是。

C#,VB.NET都會把它們編譯成托管模塊,托管模塊在一個標准的可移植的PE文件中。(那些懵懂的少年肯定慌了,這是什麼鬼,又是托管模塊又是PE文件的。莫慌,所有你聽不懂的高大上的術語其實都很簡單,你現在不需要懂,聽我慢慢道來)

所謂PE文件,就是可移植執行體,簡單來講就是.EXE和.DLL這種鬼東西(這個exe和C語言生成的有區別的)。這個PE文件裡的托管模塊,你可以當做一個對象,對象裡有四個屬性,一個PE頭(描述文件),一個CLR頭(描述這個對象的整體的一些信息,比如main入口),元數據(這個很關鍵,一種元數據表包含源代碼中定義的那些那些類型和成員的描述信息,另一種包含引用的類型和成員的描述信息),IL代碼(就是你的源代碼被編譯後的代碼,又稱中間語言)。

如果覺得麻煩,前面兩個屬性你可以忘掉了,記住後面兩個就好:元數據和IL代碼(簡單來講,就是代碼的描述信息和編譯後的代碼)。

但是一個PE文件可不只一個托管模塊,它可以由幾個托管模塊組成。編譯器會把多個托管模塊和資源文件合並成一個包含清單的程序集,這才是最後的PE文件。

運行:

但是這個托管模塊也就是PE文件並不能直接運行,他需要CLR。

CLR常用簡寫詞語,CLR是公共語言運行庫(Common Language Runtime)和Java虛擬機一樣也是一個運行時環境,它負責資源管理(內存分配和垃圾收集等),並保證應用和底層操作系統之間必要的分離。CLR存在兩種不同的翻譯名稱:公共語言運行庫和公共語言運行時。

此描述及以後的描述均來自百度百科,我懶得手打。

CLR的核心功能包括:內存管理,程序集加載,安全性,異常處理和線程同步。

這個東西又稱為公共語言運行時。

前面的說到不能直接運行的時候,這裡有懵懂的少年肯定說,我生成的exe文件明明可以直接運行。

這是因為你的電腦上安裝了.NET Framework。當你在打開exe程序的時候你的進程的主線程會調用MSCorEE.dll的一個方法,這個方法會初始化CLR,再加載exe程序集,然後調用入口方法即main函數。

所以說實際上你的代碼運行是需要在CLR上的。

那麼CLR到底是怎麼玩我們的Hello world的?

它會在運行時編譯我們的IL代碼。(先別吐槽為什麼要編譯兩次,後面有講)

早在Main函數執行之前,CLR就會檢測Main的代碼所引用的所有類型,然後生成了一個內部的數據結構來管理引用類型的訪問。

在這個內部結構中,每個類型比如Console的每個方法都會有一個入口,每個入口都有一個地址(這裡叫地址A吧),這個地址A就可以找到方法的實現代碼。

而在這個內部數據結構初始化的時候,所有的這些入口的地址都會被設置成一個叫JITCompiler的函數。

就比如上面圖中的hello world代碼第一句,CLR在執行這句代碼的時候會跑進JITCompiler這個函數中,這是內部操作:

那麼如果我們第二次去執行Writeline函數呢?此時內部結構中Writeline函數入口的地址指向的已經是編譯好的CPU指令的地址了,所以也就不會去執行JITCompiler這個函數。

千萬不要認為這樣一定會很慢哦,除了第一次運行時JITCompiler的編譯可能需要花費掉編譯和優化的時間,後來執行的就是本地CPU指令哦。再加上JITCompiler的這個編譯會根據你的機器的CPU不同可能會去生成一些專屬於本CPU的特殊指令去優化IL代碼,有的這種托管程序可能還要比非托管程序快。

好了,本章的精髓就是上面這些了。

現在我們想想為什麼要編譯兩次?

因為這樣的話,無論用C#、VB、F#這些東西你都可以生成一樣的包含IL代碼的托管程序集,然後這個托管程序集在CLR上運行,也就是說可以混合寫代碼,一個C#代碼可以調用VB代碼的DLL,用最適合的語言做最適合的事情。

並且在CLR監視之下執行的IL代碼因為在執行前會進行安全校驗,所以會提高程序的健壯性和可靠性。

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