CLR vir C# 之CLR執行模型

來源:互聯網
上載者:User

     從今天開始讀CLR vir C#.雖然是英文版,但希望能從剛剛讀完的《你必須知道的.net》中找到共鳴。

 

     本文簡單闡述從Source Code 到CPU Native Code 的執行期間,發生了什麼事?    

 把源碼編譯成Managed 程式碼

      在.net環境下,我們可以採用多種語言來進行編程,比如C#,Vb.net,J#等。並且多種語言可以同時存在於同一專案中,這涉及到了CTS的內容,暫不闡述。每種語言都有其對應的編譯器存在,C#->CS Compiler,Vb.net->Basic Compiler等。如

 

     

 

     不管什麼語言,通過各自的編譯器編譯後,都會產生PE檔案(Portable Executable file)也即託管模組(Managed Module).通常託管模組包括以下幾部分:
     1.PE(32) Header

     2.CLR Header (兩者描述一些附加資訊)

     3.MetaData  (主要包括兩個原資料表:一個描述源碼中的類型和成員資訊,一個面熟源碼引用到的類型和成員資訊)

     4.IL(中間代碼:不管哪種程式設計語言(net支援的),都要編譯為統一的中間代碼)

     注意:中繼資料在這裡是個很重要的角色,由於它的“自我描述”(由兩個原資料表決定了)簡單的來說,它可以:

     1)造就了net的智能感知

     2)允許對象的欄位被序列化與還原序列化(*)

     3)使得GC可以追蹤到對象的參考關聯性,得到對象的生命週期

     4)保證了編寫安全的代碼(*)

 

     託管模組產生Assembly

     到達中間代碼,接下來好像就輪到CLR 的JIT編譯機制,在運行時把其編譯成本地代碼即可。實際上,CLR是不與managed module發生作用的,managed module要首先由對應的編譯器編譯成Assembly(DLL, exe)後,CLR與Assembly互動。見:
     

 

     根據我們平時的編程經驗來理解上述Assembly產生:比如一個winform專案,裡麵包括form ,images等資源,編譯時間,可以選擇產生類庫(DLL),或者可執行檔(EXE),這個時候,就會把所有的資源(源碼,images)等全部“打包”成一個DLL/Exe,如果是建立類庫的專案則更加如此。

     當然,產生的Assembly(DLL/Exe)要想在用戶端運行,需要CLR的支援,這也就是為什麼我們在部署的winform專案的時候,在client端安裝framework的原因了。

     JIT執行Assembly

     從上面的描述中可以知道,產生的Assembly是在運行時由JIT進行編譯執行的,而這個過程正式託管程式效能的一個很到的體現:

     如下代碼:
     

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

     當第一次調用WriteLine方法時,

     1.JIT Compiler從中繼資料中找到要調用的方法,

     2.從而找到方法在IL中的位置,這個動作可以從上面對中繼資料的描述中得到得以解釋。

     3.分配空間

     4.JIT把IL編譯成本地代碼

           (註:這個過程中實際上還有一個動作:Verification(驗證),此驗證用來保證代碼的安全性。比如驗證方法參數是否一致,傳回值是否正常返回等。)

     5.把產生的本地代碼儲存在動態產生的記憶體空間中

     6.運行指標跳轉至本地代碼執行

     這個過程簡單的闡述了運行時的JIT工作流程。

     當第二次調用WriteLine方法時,由於在本地記憶體中已經儲存有此方法的本地代碼,所以JIT的編譯過程將被繞過,直接執行本地代碼,從而使執行效能得到提高。

     從這個角度看,我們平時講的封裝和複用等思想,在代碼最佳化,效能提高方法都會起到很好的作用。

     當然,如果應用程式關閉,動態記憶體得以釋放,產生的本地代碼也就不存在了。

 

      CTS一般型別系統

     上文中提到,net實現了多語言的互操作,這個特性需要CTS和CLS的支援。

     CTS中定義類型中能夠定義什麼,如何定義等規範,並對類型的存取層級做了規範(private,famlily,public等),可以看到,裡面的定義如family實際上對應的IL中的定義,具體的每種語言中都有自己的映射定義,如protected.

     又比如對資料類型的定義,CTS中的Int32,在C#中可以為int即可。這些只是

一些映射定義,編譯為IL後,實際還是要稱為CTS中定義的類型Int32.

     這種特性,就使得開發人員可以用自己熟悉的語言,自己熟悉的文法進行編程,完成後還可以進行與其他語言代碼的互動。

     而相反,沒有在CTS中定義的規範,在具體的語言中是停用:比如C++語言支援多繼承,而在CTS中定義對於類只是是單向單繼承,所以net環境下寫C++代碼就必須符合這個規範,寫多繼承的代碼會出現編譯錯誤。

     CLS通用文法規範

     如果說CTS定義了統一的編程規範,那麼CLS就定義了實現語言互操作每種語言必須符合的最小集合。

     如果要實現互操作的編碼,可以使用[assembly:CLSCompliant(true)] 特性,來檢查代碼是否符合CLS規範。

Code
using System;
using System.Runtime.InteropServices;
[assembly:CLSCompliant(true)]

namespace Demo1
{
   public class cls
    {
        static void Main(string[] args)
        {

        }

        public UInt32 foo()
        {
            UInt32 i = 10;
            return i;
        }
    }
}

     由於在VB.net中不存在Uint32的定義,所以foo方法會得到警告:不符合CLS規範。

     具體的規範內容,需要參考相關文檔得知。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.