Share via


應用程式定義域和組件

這個主題是描述應用程式定義域和組件之間的關聯性。 您必須先將組件載入到應用程式定義域之後,才能執行它所包含的程式碼。 執行一個典型的應用程式會讓好幾個組件載入應用程式定義域。

載入組件的方式會決定其 Just-in-Time (JIT) 編譯程式碼是否能在處理序中由多個應用程式定義域所共用,以及組件是否能夠從處理序卸載。

  • 如果組件是以定義域中性方式 (Domain-neutral) 載入,所有共用相同安全性授權集的應用程式定義域,也就都能共用相同的 JIT 編譯程式碼,進而減少應用程式所需要的記憶體。 然而,組件則會永遠無法從處理序中卸載。

  • 如果組件不是以定義域中性方式載入,則在載入該組件的每一個應用程式定義域中,都必須是 JIT 編譯的。 然而,只要卸載所有載入該組件的應用程式定義域,即可從處理序中卸載組件。

執行階段主機會判斷將執行階段載入處理序時,是否要以定義域中性方式載入組件。 針對 Managed 應用程式,會將 LoaderOptimizationAttribute 屬性 (Attribute) 套用到處理序的進入點方法,並從關聯的 LoaderOptimization 列舉型別 (Enumeration) 中指定值。 針對裝載 Common Language Runtime 的 Unmanaged 應用程式,指定您在呼叫 CorBindToRuntimeEx 函式 方法時的適當旗標。

載入定義域中性組件的選項有三種:

  • 除了永遠以定義域中性方式載入的 Mscorlib 之外,SingleDomain 不會以定義域中性方式載入任何組件。 這種設定稱為單一定義域,因為它通常使用於裝載程式只在處理序中執行單一應用程式的情況。

  • MultiDomain 會將所有組件都以定義域中性方式載入。 處理序中有多個應用程式定義域,而且它們全部都執行相同的程式碼時,請使用這種設定。

  • 如果強式名稱組件及其所有相依性項目都已安裝在全域組件快取中,MultiDomainHost 便會以定義域中性方式載入這些組件。 其他組件都會分別載入並針對載入組件的每個應用程式定義域進行 JIT 編譯,因此這些組件都可以從處理序中卸載。 在相同處理序中執行多個應用程式時,或是有許多應用程式定義域及組件 (需要從處理序卸載) 共用的混合組件時,請使用這項設定。

對於使用 Assembly 類別 (Class) 的 LoadFrom 方法將載入內容載入的組件,以及使用指定位元組陣列之 Load 方法的多載而自影像載入組件,都無法共用 JIT 編譯程式碼。

已經使用Ngen.exe (原生映像產生器) 編譯成機器碼的組件,如果在第一次載入處理序時,是以定義域中性方式載入的,就可以在應用程式定義域之間共用。

針對包含應用程式進入點的組件,只有在能夠共用組件的所有相依性項目時,才能共用其 JIT 編譯程式碼。

對於以定義域中性方式載入的組件,可以進行一次以上的 JIT 編譯。 例如,當兩個應用程式定義域的安全性授權集不同時,兩者就不能共用相同的 JIT 編譯程式碼。 然而,JIT 編譯組件的每個複本都能與具有相同授權集的其他應用程式定義域共用。

在決定是否要將組件以定義域中性方式載入時,您必須在減少記憶體使用與其他效能考量之間做出取捨。

  • 對於定義域中性的組件,存取靜態資料和方法會比較緩慢,這是因為需要隔離組件。 存取該組件的每一個應用程式定義域都必須有靜態資料的單獨複本,以避免靜態欄位中物件的參考跨越定義域界限。 而其結果是,執行階段會含有額外的邏輯以便將呼叫端導向至靜態資料或方法的適當複本。 這些額外的邏輯就會讓呼叫慢下來。

  • 在將組件以定義域中性方式載入時,必須找到和載入組件的所有相依性項目。這是因為無法以定義域中性方式載入的相依性項目,也會使組件無法以定義域中性方式載入。

請參閱

概念

應用程式定義域

Common Language Runtime 中的組件