アプリケーション ドメインとアセンブリ
ここでは、アプリケーション ドメインとアセンブリの関係について説明します。 アセンブリに含まれるコードを実行する前に、そのアセンブリをアプリケーション ドメインに読み込む必要があります。 通常のアプリケーションを実行すると、複数のアセンブリがアプリケーション ドメインに読み込まれます。
アセンブリが読み込まれる方法によって、そのアセンブリの Just-In-Time (JIT) コンパイル コードをプロセス内の複数のアプリケーション ドメインで共有できるかどうか、およびアセンブリをプロセスからアンロードできるかどうかが決まります。
アセンブリがドメインに中立として読み込まれる場合は、同じセキュリティ許可セットを共有するすべてのアプリケーション ドメインが同じ JIT コンパイル コードを共有できるため、アプリケーションに必要なメモリを削減できます。 ただし、アセンブリをプロセスからアンロードできなくなります。
アセンブリがドメインに中立として読み込まれない場合は、そのアセンブリが読み込まれる各アプリケーション ドメインで、そのアセンブリを JIT でコンパイルする必要があります。 ただし、アセンブリが読み込まれているアプリケーション ドメインをすべてアンロードすることで、プロセスからアセンブリをアンロードできます。
ランタイム ホストは、ランタイムをプロセスに読み込むときに、アセンブリをドメインに中立なアセンブリとして読み込むかどうかを決定します。 マネージ アプリケーションの場合は、LoaderOptimizationAttribute 属性をプロセスのエントリ ポイント メソッドに適用し、関連付けられた LoaderOptimization 列挙体から値を指定します。 共通言語ランタイムをホストするアンマネージ アプリケーションの場合は、CorBindToRuntimeEx 関数 メソッドを呼び出すときに適切なフラグを指定します。
アセンブリをドメインに中立として読み込むかどうかに関して、次の 3 つのオプションがあります。
SingleDomain では、常にドメインに中立として読み込まれる Mscorlib を除き、どのアセンブリもドメインに中立として読み込まれません。 この設定は、ホストがプロセス内で 1 つのアプリケーションだけを実行する場合に一般的に使用されるため、シングル ドメインと呼ばれます。
MultiDomain では、すべてのアセンブリがドメインに中立として読み込まれます。 この設定は、同じコードを実行する複数のアプリケーション ドメインが 1 つのプロセス内に存在する場合に使用します。
MultiDomainHost では、厳密な名前が付いたアセンブリとそのすべての依存関係がグローバル アセンブリ キャッシュにインストールされている場合に、それらのアセンブリがドメインに中立として読み込まれます。 その他のアセンブリは、それらが読み込まれる各アプリケーション ドメインで個別に読み込まれ、JIT でコンパイルされるため、プロセスからアンロードできます。 この設定は、同じプロセスで複数のアプリケーションが実行されている場合、または多数のアプリケーション ドメインで共有されているアセンブリと、プロセスからアンロードする必要があるアセンブリが混在している場合に使用します。
Assembly クラスの LoadFrom メソッドを使用して読み込み元を指定して読み込まれたアセンブリ、またはバイト配列を指定する Load メソッドのオーバーロードを使用してイメージから読み込まれたアセンブリについては、JIT コンパイル コードを共有できません。
Ngen.exe (ネイティブ イメージ ジェネレーター) を使用してネイティブ コードにコンパイルされたアセンブリは、プロセスに最初に読み込まれるときにドメインに中立として読み込まれていれば、アプリケーション ドメイン間で共有できます。
アプリケーションのエントリ ポイントを含むアセンブリの JIT コンパイル コードは、そのすべての依存関係を共有できる場合にだけ共有されます。
ドメインに中立なアセンブリは、JIT で複数回コンパイルできます。 たとえば、2 つのアプリケーション ドメインのセキュリティ許可セットが異なっている場合、それらのドメインは同じ JIT コンパイル コードを共有できません。 ただし、JIT コンパイル アセンブリの各コピーは、同じ許可セットを持つ他のアプリケーション ドメインと共有できます。
アセンブリをドメインに中立として読み込むかどうかを判断する場合は、メモリ使用量の削減とその他のパフォーマンス要因とのトレードオフを考慮する必要があります。
ドメインに中立のアセンブリでは、アセンブリを分離する必要があることから、静的データおよびメソッドにアクセスする速度が遅くなります。 静的フィールド内のオブジェクトがドメイン境界を越えて参照されることがないように、アセンブリにアクセスする各アプリケーション ドメインが、静的データのコピーを個別に保持する必要があるためです。 その結果、ランタイムには、呼び出し元が静的データまたは静的メソッドの適切なコピーにアクセスできるようにするための追加のロジックが必要となります。 この追加のロジックのために、呼び出しの処理速度が低下します。
アセンブリがドメインに中立で読み込まれるときに、アセンブリのすべての依存関係を探し出して読み込む必要があります。これは、ドメインに中立として読み込むことのできない依存関係があると、アセンブリをドメインに中立として読み込むことができなくなるからです。