1. 程式人生 > >System.AppDomain類詳解(一)

System.AppDomain類詳解(一)

AppDomain是CLR(Common Language Runtime:公共語言執行庫),它可以載入Assembly、建立物件以及執行程式。

AppDomain是CLR實現程式碼隔離的基本機制。

每一個AppDomain可以單獨執行、停止;每個AppDomain都有自己預設的異常處理;一個AppDomain的執行失敗不會影響到其他AppDomain的執行。

CLR在被CLR Host(windows shell or InternetExplorer or SQL Server)載入後,會建立一個預設的AppDomain,程式的入口點(main方法)就是在這個預設的AppDomain中執行。

1、AppDomain與程序比較:

AppDomain被建立是在程序中,一個程序中可以有多個AppDomain,但一個AppDomain只能屬於一個程序。

2、AppDomain與執行緒比較:

與執行緒,Appdomain是個靜態概念,知識限定了物件的邊界;執行緒是個動態的概念,它可以執行在不同的AppDomain中。一個AppDomain內可以建立多個執行緒,但是不能限定這些執行緒只能在本AppDomain內執行程式碼。

CLR中的System.Threading.Thread物件其實是個soft thread,它並不能被作業系統識別;作業系統能識別的是hard thread。一個soft thread只屬於一個ppDomain,穿越AppDomain的是hard thread。當hard thread訪問到某個AppDomain時,一個AppDomain就會產生一個soft thread。

hard thread有thread local storage(TLS),這個儲存區被CLR用來儲存hard thread當前對應的AppDomain引用以及soft thread引用。當一個hard thread穿越到另外一個AppDomain時,TLS中的這些引用也會改變。

3、AppDomain與Assembly的比較:

Assembly是.net程式的基本部署單元,它可以為CLR提供識別型別的元資料等等。Assembly不能單獨執行,必須被載入到AppDomain中,然後由AppDomain建立程式集中的物件。一個Assembly可以被多個AppDomain載入,一個AppDomain可以載入多個Assembly。每個AppDomain引用到某個型別的時候需要把相應的assembly在各自的AppDomain中初始化。因此,每個AppDomain會單獨保持一個類的靜態變數。

4、AppDomain與物件的比較:

任何物件只能屬於一個AppDomain,AppDomain用來隔離物件,不同AppDomain之間的物件必須通過Proxy(reference type)或者Clone(value type)通訊。

引用型別需要繼承System.MarshalByRefObject才能被Marshal/UnMarshal(Proxy)。
    值型別需要設定Serializable屬性才能被Marshal/UnMarshal(Clone)。

5、AppDomain與Assembly Code

AppDomain和程式集的原始碼是什麼關係呢?每個程式集的程式碼會分別裝載到各個AppDomain中?
    首先我們要把程式集分3類
    1.mscorlib,這是每個.net程式都要引用到的程式集。
    2.GAC,這個是強命名的公用程式集,可以被所有的.net程式引用。
    3.Assembly not in GAC,這是普通的assembly,可以不是強命名,不放到GAC中。
      啟動CLR,進入entry point時可以設定LoaderOptimization屬性:
      [LoaderOptimization(LoaderOptimization.MultiDomain]
      static void Main()
      {…}
    LoaderOptimization屬性可以設定三個不同的列舉值,來設定針對前面說的三種程式集的程式碼存放以及訪問方式。
    LoaderOptimization Enumeration/Attribute
    
Value Expected Domains in Process Each Domain Expected to Run … Code for MSCORLIB Code for Assemblies in GAC Code for Assemblies not in GAC
SingleDomain One N/A Per-process Per-domain Per-domain
MultiDomain Many Same Program Per-process Per-process Per-process
MultiDomainHost Many Different Programs Per-process Per-process

Per-domain     1.SingleDomain,由於只啟動一個AppDomain,那麼code就被直接裝載到了AppDomain中,訪問靜態變數更快捷。
    2.MultiDomain,所有的Assembly程式碼是程序級別的,因此所有的AppDomain只訪問一份程式碼。這大大減少了程式佔用的記憶體,但是由於程式集的靜態變數仍然在各個AppDomain中,因此程式碼訪問靜態變數需要先得到AppDomain的引用再進行轉換,速度會受到影響。
    3.MultiDomainHost,只有GAC程式碼是共享的,非GAC的Assembly依然會載入到被使用的AppDomain中,這樣提高靜態變數的訪問速度,當然也增加程式佔用記憶體。
    不管是哪種方式,mscorlib始終是process級別的,即只有一份mscorlib程式碼在記憶體中。

詳細參考:http://www.cnblogs.com/foman/archive/2009/10/18/1585655.html