日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
.NETCRL程序載入原理大揭秘

.NET這個(gè)詞語對我們不陌生吧,而.Net平臺下CLR程序程序怎么載入呢?這個(gè)有有些人就步知道了,在這里給大家分析以下原理。與傳統(tǒng)的Win32可執(zhí)行程序中的本機(jī)代碼(Native Code)不同,微軟推出的.Net架構(gòu)中,可執(zhí)行程序的代碼是以類似Java Byte Code的 IL (Intermediate Language)偽代碼形式存在的。在.Net可執(zhí)行程序載入后,IL代碼由CLR (Common Language Runtime)從可執(zhí)行文件中取出, 交由JIT (Just-In-Time)編譯器,根據(jù)相應(yīng)的元數(shù)據(jù)(Metadata),實(shí)時(shí)編譯成本機(jī)代碼后執(zhí)行。
 
因此,一個(gè).NET CRL下的可執(zhí)行程序的啟動過程可以分為三個(gè)步驟。
首先,Windows的可執(zhí)行程序載入器(OS Loader)載入 PE (Portable Executable)結(jié)構(gòu)的可執(zhí)行文件映像(PE Image),將執(zhí)行權(quán)傳遞給CLR的支持庫中的Unmanaged Code。
其次,啟動或使用現(xiàn)有的CLR引擎,建立新的應(yīng)用域(Application Domain),將配件(Assembly)載入到此應(yīng)用域中。
最后,將執(zhí)行權(quán)從Unmanaged Code傳遞給Managed Code,執(zhí)行配件的代碼。

下面我將詳細(xì)說明以上步驟。
 
自從Win95發(fā)布以來,可執(zhí)行程序的PE結(jié)構(gòu)就沒有發(fā)生大的改動。此次.Net平臺發(fā)布,也只是利用了PE結(jié)構(gòu)中現(xiàn)有的預(yù)留空間,以保持PE結(jié)構(gòu)的穩(wěn)定,最大程度保持向后兼容。CLR程序在編譯后,將可執(zhí)行程序入口直接以一個(gè)間接跳轉(zhuǎn)指令 ,指向mscoree.lib中的_CorExeMain函數(shù)(DLL將入口指向_CorDllMain函數(shù))。因此CLR可執(zhí)行程序在被OS Loader載入后,將_CorExeMain函數(shù)處理CLR引擎 ,啟動事宜。此函數(shù)將啟動或使用一個(gè)現(xiàn)有的CLR Host來加載IL代碼。常見的CLR Host有ASP.Net、IE、Shell、數(shù)據(jù)庫引擎等等,他們的作用是啟動一個(gè)CLR實(shí)例,管理在此CLR實(shí)例中運(yùn)行的CLR程序。我們接著來看一看一個(gè)CLR Host是如何實(shí)際運(yùn)作的。

CLR作為一個(gè)引擎,在同一臺計(jì)算機(jī)上是可以存在多個(gè)版本的,不同版本之間可以通過配置良好共存。在 %windir%\Microsoft.NET\Framework (%windir%表示W(wǎng)indows系統(tǒng)目錄所在位置)目錄下我們可以看到以版本號為目錄名的多個(gè)CLR版本, 如%windir%\Microsoft.NET\Framework\v1.0.3705等等,也可以在注冊表的

 
 
 
  1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy\v1.0  

鍵下查看詳細(xì)的版本兼容性.Name是Build號,Value是兼容的Build號. 而每一個(gè)CLR版本又分為Server和Workstation兩類運(yùn)行庫, 我們等會講創(chuàng)建.NET CLR時(shí)會詳細(xì)談到. CLR Host在啟動CLR之前,必須通過一個(gè)startup shim的庫進(jìn)行操作, 實(shí)際上就是mscoree.dll,他提供了版本無關(guān)的操作函數(shù),以及啟動CLR所需 的支持,如CorBindToRuntimeEx函數(shù). CLR Host通過shim的支持庫,將CLR引擎載入到進(jìn)程中.具體函數(shù)如下

 
 
 
  1. STDAPI CorBindToRuntimeEx(LPCWSTR pwszVersion,   
  2. LPCWSTR pwszBuildFlavor, DWORD startupFlags,   
  3. REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);  

參數(shù)pwszVersion指定要載入的CLR版本號,注意必須在前面帶一個(gè)小寫的"v", 如"v1.0.3705",可以通過查閱前面提到的注冊表鍵,獲取當(dāng)前系統(tǒng)安裝的不同CLR 版本情況,或指定固定的CLR版本.也可以遞NULL給這個(gè)參數(shù),系統(tǒng)將自動選擇最新版本的CLR載入. 參數(shù)pwszBuildFlavor則指定載入的CLR類型,"srv"和"wks". 前者適用于多處理器的計(jì)算機(jī),能夠利用多CPU提高并行性能.對單CPU系統(tǒng)而言,無論指定哪種類型都會載入"wks",傳遞NULL也是如此. 參數(shù)startupFlags是一個(gè)組合參數(shù).由多個(gè)標(biāo)志位組成. STARTUP_CONCURRENT_GC標(biāo)志指定是否使用并發(fā)的GC(Garbage Collection) 機(jī)制,使用并發(fā)GC能夠提高系統(tǒng)的用戶界面相應(yīng)效率,適合窗口界面使用較多的程序. 但并發(fā)GC會因?yàn)闊o謂的線程上下文(Thread Context)切換損失效率.

以下三個(gè)參數(shù)用于指定配件載入優(yōu)化策略.我們等會詳細(xì)討論.

 
 
 
  1. STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN = 0x1 << 1,   
  2. STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN  = 0x2 << 1,   
  3. STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST = 0x3 << 1,  

接著的三個(gè)參數(shù)用于獲取ICorRuntimeHost接口.

實(shí)際調(diào)用實(shí)例如下.

 
 
 
  1. CComPtr spHost;   
  2. CHECK(CorBindToRuntimeEx(NULL, L"wks",   
  3. STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,   
  4. CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&spHost)); 

這行代碼載入最高版本CLR的wks類型運(yùn)行庫,為單應(yīng)用域進(jìn)行優(yōu)化并使用并發(fā)GC機(jī)制. 前面提到了配件載入優(yōu)化策略,要理解這個(gè)概念,我們必須先了解應(yīng)用域的概念. 傳統(tǒng)Win程序中,資源的分配管理單位是進(jìn)程,操作系統(tǒng)以進(jìn)程邊界將應(yīng)用程序?qū)嵗綦x開, 單個(gè)進(jìn)程的崩潰不會對其他進(jìn)程產(chǎn)生直接影響,進(jìn)程也不能直接使用其他進(jìn)程的資源. 進(jìn)程很好,但使用進(jìn)程的代價(jià)太大,為此Win32引入了線程的概念.同一進(jìn)程中的線程能夠共享資源,線程管理和切換的代價(jià)也遠(yuǎn)遠(yuǎn)小于進(jìn)程.但因?yàn)樵谕贿M(jìn)程中,線程的崩潰會直接影響到其他線程的運(yùn)行,也無法約束線程間數(shù)據(jù)的直接訪問等等. 為此,CLR Application Domain應(yīng)用域的概念.應(yīng)用域是介于進(jìn)程和線程之間的一種邏輯上的概念.他既有線程輕巧,管理切換快捷的優(yōu)點(diǎn),也有進(jìn)程在穩(wěn)定性方面的優(yōu)點(diǎn),單個(gè)應(yīng)用域的崩潰不會直接影響到同一進(jìn)程中的其他應(yīng)用域,應(yīng)用域也無法直接訪問同一進(jìn)程中的其他應(yīng)用域的資源,這方面和進(jìn)程完全相同. 而.NET CLR的管理就是完全面向應(yīng)用域一級.CLR不能卸載(Unload)某個(gè)類型或配件, 必須以應(yīng)用域?yàn)閱挝粏?停止代碼,獲取/釋放資源.

CLR在執(zhí)行一個(gè)配件時(shí),會新建一個(gè)應(yīng)用域,將此配件放入新的應(yīng)用域.如果多個(gè)應(yīng)用域同時(shí)使用到一個(gè)配件,就要涉及到前面提到的配件載入優(yōu)化策略了.最簡單的方法是使用

STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN標(biāo)志,每個(gè)應(yīng)用域擁有一份獨(dú)立的配件的鏡像,這樣速度最快,管理最方便,但占用內(nèi)存較多.相對的是所有應(yīng)用域共享一份配件的鏡像,(使用STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN標(biāo)志) 這樣節(jié)約內(nèi)存,但在此配件中存在靜態(tài)變量等數(shù)據(jù)時(shí),因?yàn)橐WC每個(gè)應(yīng)用域有獨(dú)立的數(shù) 據(jù), 所以會一定程度上影響效率.折中的方案是使用 (使用STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST標(biāo)志) 此時(shí),只有那些有Strong Name的配件才會被多個(gè)應(yīng)用域共享.

這里又涉及到一個(gè)概念Strong Name.他是一個(gè)配件的身份證明,他由配件的 名字/版本/culture以及數(shù)字簽名等組成.在配件發(fā)布時(shí)用以區(qū)別不同版本. 也在安全/版本控制等方面起到重要作用,以后有機(jī)會會專門講解.暫且跳過. 獲取了ICorRuntimeHost接口的指針后,我們可以以此指針取得當(dāng)前/缺省應(yīng)用域,
并可枚舉CLR引擎實(shí)例中所有的應(yīng)用域.

【編輯推薦】

  1. SQL SERVER 2005 CLR集成之簡單SQL函數(shù)講解
  2. 代碼演示CLR Via C#如何調(diào)用靜態(tài)構(gòu)造函數(shù)
  3. 概述講解SQL Server 2005 CLR集成執(zhí)行功能
  4. 簡單概述SQLCLR CAS權(quán)限集
  5. 全面講解CLR安全性

文章標(biāo)題:.NETCRL程序載入原理大揭秘
文章源于:http://www.dlmjj.cn/article/dpgihsd.html