天天看点

.NET编译器中CLR加载过程

按以下贴操作的:

<a href="http://developer.51cto.com/art/200908/146091.htm">http://developer.51cto.com/art/200908/146091.htm</a>

由于现在不太了解VS即时窗口,所以后面的测试没有作。

以前,看《程序员的自我修养》,讲解文件PE格式时,也涉及到这些内容。但主要以直接加载过程为主。

而现在.NET为主流了。所以要多学习呀。

.NET的几个核心组件的被调用顺序大致是: mscoree.dll -----&gt; mscorwks.dll(mscorsvr.dll) 

-----&gt; mscorlib.dll -----&gt;mscorjit.dll。

结合蔡学镛的说明与JVM的载入比较如下:

執行 Main.exe 時,.NET CLR 啟動的方式如下:

Windows 所提供的 PE Loader 將 Main.exe 載入記憶體

Windows 所提供的 PE Loader 將 MsCorEE.dll 載入記憶體 (MsCorEE.dll 位於 C:\WINDOWS\System32 或                             C:\WINNT\System32)

程式跳到 MsCorEE.dll 內的 _CorExeMain()

_CorExeMain() 會載入「適當版本的」.NET CLR。如果你的 .NET 是 1.0.3705 版,則 .NET CLR 位於 C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705                             或者 C:\WINNT\Microsoft.NET\Framework\v1.0.3705

程式跳到 .NET CLR,進行一些初始化工作 (initialization)

載入assembly「MsCorLib」,載入module「MsCorLib.dll」,載入 MsCorLib 內的某些 class

產生主執行緒 (main thread)

載入「Main」組件,載入「Main.exe」模組,載入「MainClass」類別

讓主執行緒開始執行 MainClass.Main()

~~~~~~~~~~~~

Java 的作法是先執行 VM (由 java.exe 進入),再請 VM 去執行 Java bytecode。.NET 的作法是,先執行 .NET PE,立刻將控制權轉給 .NET CLR,再由 .NET CLR 來執行 .NET PE。.NET 的作法固然使用上比 Java 方便,但其實 .NET 需要 OS 的 loader配合,而 Java 不需要。

上述第 4 點提及 _CorExeMain() 會載入「適當版本的」.NET CLR。其實 MsCorEE.dll 不是 CLR,只是一個填隙程式 (shim),負責搭起.NET PE 和 .NET CLR 之間橋樑。MsCorEE 會匯集足夠的資料,然後據以判斷要載入 Workstation 版 (MsCorWks.dll) 或者 Server 版 (MsCorSvr.dll) 的 .NET CLR。以本例來說,被載入的是 Workstation 版的 MsCorWks.dll。在載入MsCorWks.dll 之後,還會陸續載入 fusion.dll、MsCorSn.dll、MsCorJIT.dll 等 DLL 檔。

事實上 java.exe 的角色和 MsCorEE.dll 的角色一樣,負責喚起適當版本的 JVM。如果你安裝的是 1.4.x 的 J2SE SDK 而非 1.4.x的 JRE,你的 JDK 內會同時具備 client 和 server 兩個 JVM,分別在 JDK 目錄下的 jre\bin\client\jvm.dll 與 jre\bin\server\jvm.dll。

.NET编译器中CLR加载过程