動的な型生成のための収集可能なアセンブリ

収集可能なアセンブリとは、そのアセンブリが作成されたアプリケーション ドメインをアンロードせずに、アンロードできる動的アセンブリです。 収集可能なアセンブリとそのアセンブリ内の型で使用されていたマネージ メモリとアンマネージ メモリは、すべて再利用できるようになります。 アセンブリ名などの情報は内部テーブルから削除されます。

アンロードを有効にするには、動的アセンブリの作成時に AssemblyBuilderAccess.RunAndCollect フラグを使用します。 このアセンブリは一時的なものであり (つまり保存できません)、「収集可能なアセンブリに対する制限」で説明されている制限が適用されます。 収集可能なアセンブリは、そのアセンブリに関連付けられているすべてのオブジェクトが解放されると、共通言語ランタイム (CLR: Common Language Runtime) によって自動的にアンロードされます。 その他のすべての点では、収集可能なアセンブリは他の動的アセンブリと同じように作成および使用されます。

収集可能なアセンブリの有効期間

収集可能な動的アセンブリの有効期間は、そのアセンブリに含まれる型への参照があるかどうかと、それらの型から作成されたオブジェクトがあるかどうかによって決まります。 次の 1 つ以上が存在する限り、共通言語ランタイムはアセンブリをアンロードしません (T は、アセンブリで定義されている任意の型です)。

  • T のインスタンス。

  • T の配列のインスタンス、または T を型引数の 1 つとして含んでいるジェネリック コレクションのインスタンス (配列またはコレクションが空の場合を含む)。

  • T を表す Type または TypeBuilder のインスタンス。

メモメモ

アセンブリの一部を表すオブジェクトをすべて解放する必要があります。T を定義した ModuleBuilderTypeBuilder への参照を保持し、AssemblyBuilder オブジェクトは ModuleBuilder への参照を保持します。したがって、これらのオブジェクトへの参照も解放する必要があります。T の構築に使用された LocalBuilderILGenerator が存在している場合も、アンロードは行われません。

  • 実行コードから到達できる動的に定義された別の型 T1 による、T への静的参照。 たとえば、T1 が T から派生している場合や、T が T1 のメソッドのパラメーターの型である場合があります。

  • T に属する静的フィールドに対する ByRef。

  • T または T のコンポーネントを参照する RuntimeTypeHandleRuntimeFieldHandle、または RuntimeMethodHandle

  • T を表す Type オブジェクトへのアクセスに間接または直接に使用できるリフレクション オブジェクトのインスタンス。 たとえば、T を表す Type オブジェクトは、要素型が T である配列型や、T を型引数として持つジェネリック型から取得できます。

  • 任意のスレッドの呼び出し履歴にあるメソッド M。この M は、T のメソッド、またはアセンブリで定義されているモジュール レベルのメソッドです。

  • アセンブリのモジュール内で定義されている静的メソッドに対するデリゲート。

アセンブリ内の 1 つの型または 1 つのメソッドについてだけでも、この一覧の項目が 1 つでも存在する場合、そのアセンブリをアンロードすることはできません。

メモメモ

実際には、この一覧にあるすべての項目に対してファイナライザーが実行されるまで、アセンブリはアンロードされません。

有効期間の追跡では、収集可能なアセンブリの生成時に作成および使用される List<int> (Visual Basic では List(Of Integer)) などの構築ジェネリック型は、そのジェネリック型定義を含むアセンブリか、その型引数のいずれかの定義を含む別のアセンブリで定義されていると見なされます。 使用される正確なアセンブリは実装の詳細であり、変更されることがあります。

収集可能なアセンブリに対する制限

収集可能なアセンブリには、次の制限があります。

  • 静的参照   通常の動的アセンブリ内の型では、収集可能なアセンブリで定義されている型への静的参照を使用できません。 たとえば、収集可能なアセンブリ内の型を継承する通常の型を定義すると、NotSupportedException 例外がスローされます。 収集可能なアセンブリ内の型では、別の収集可能なアセンブリ内の型への静的参照を使用できますが、この場合は、参照アセンブリの有効期間が参照元アセンブリの有効期間に延長されます。

  • COM 相互運用   収集可能なアセンブリ内では COM インターフェイスを定義できません。また、収集可能なアセンブリ内の型のインスタンスを COM オブジェクトに変換することもできません。 収集可能なアセンブリ内の型は、COM 呼び出し可能ラッパー (CCW: COM Callable Wrapper) またはランタイム呼び出し可能ラッパー (RCW: Runtime Callable Wrapper) として機能できません。 ただし、収集可能なアセンブリ内の型では、COM インターフェイスを実装するオブジェクトを使用できます。

  • プラットフォーム呼び出し   DllImportAttribute 属性を持つメソッドを収集可能なアセンブリ内で宣言しても、コンパイルはできません。 OpCodes.Calli 命令は、収集可能なアセンブリ内の型の実装では使用できません。このような型をアンマネージ コードにマーシャリングすることはできません。 ただし、収集可能でないアセンブリ内で宣言されているエントリ ポイントを使用すれば、ネイティブ コードを呼び出すことができます。

  • マーシャリング   収集可能なアセンブリで定義されているオブジェクト (特にデリゲート) はマーシャリングできません。 この制限は、一時的に生成されるすべての型に適用されます。

  • アセンブリ読み込み   収集可能なアセンブリを読み込むためにサポートされる機構は、リフレクション出力だけです。 それ以外の形式のアセンブリ読み込みによってロードされたアセンブリは、アンロードできません。

  • コンテキスト バインド オブジェクト   コンテキストの静的変数はサポートされません。 収集可能なアセンブリ内の型は、ContextBoundObject を拡張できません。 ただし、別の場所で定義されているコンテキスト バインド オブジェクトを、収集可能なアセンブリのコードで使用することはできます。

  • スレッドの静的データ   スレッドの静的変数はサポートされません。

参照

その他の技術情報

動的メソッドおよびアセンブリの出力