-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ApplicationDomain
- 戻る(.NET開発)
-
Windows ネイティブのプログラムではメモリ アドレス空間は、プロセス単位で分割されるが、
.NET では、プロセスより小さい単位のアプリケーション ドメイン単位で
メモリ(オブジェクト・リソース)が分割される。 -
また、コード・アクセス・セキュリティの設定なども、
アプリケーション ドメイン単位で行われる。
補足(何のためにあったのか): アプリケーション ドメイン(AppDomain)は、
**「プロセスを分けずに、隔離された実行単位を作る」**ための仕組みである。【プロセス】 OS が用意する隔離。確実だが、起動が重く、通信も高コスト 【アプリケーション ドメイン】 CLR が用意する隔離。1 プロセス内に複数持てる ・型・静的フィールドが独立する ・アセンブリを個別にロードでき、ドメインごとアンロードできる ・障害を封じ込められる(はずだった)代表的な用途は次の通りだった。
用途 内容 IIS / ASP.NET サイトごとに AppDomain を作り、1 ワーカー プロセスに同居させる プラグイン 信頼できないコードを隔離し、不要になったらアンロード 単体テスト ランナー テストごとに静的状態をリセットする 「アセンブリは個別にアンロードできないが、AppDomain ごとなら捨てられる」
という点が最大の存在理由だった。
移行メモ(正誤・重要): 原文の
「.NET では、プロセスより小さい単位のアプリケーション ドメイン単位で
メモリが分割される」という記述は、
.NET Framework については正しいが、
現在の .NET(Core 以降)では成り立たない。
.NET Framework .NET Core / .NET 5 以降 AppDomain の作成 可能( AppDomain.CreateDomain)不可( PlatformNotSupportedException)既定のドメイン あり 1 つだけ(API は互換のため残る) アンロード 可能 不可 分離の単位 AppDomain プロセス / コンテナ コード アクセス セキュリティ あり 廃止 廃止された理由は主に次の 3 点である。
- クロスプラットフォームで実装が困難だった
- 境界越えのコストが高い(
MarshalByRefObjectによるリモート処理)- 隔離として不完全だった
(メモリ破壊やスタック オーバーフローはプロセス全体を巻き込む)現在の代替は次の通り。
かつての用途 現在の手段 サイトごとの隔離 プロセス分離 / コンテナ(Kestrel は 1 プロセス 1 アプリ) プラグインのアンロード AssemblyLoadContext(collectible なコンテキスト)信頼できないコードの実行 別プロセス / サンドボックス / WASM 静的状態のリセット プロセスを分ける(テスト ランナーもそうしている) // 現在のプラグイン読み込み(アンロード可能なコンテキスト) var alc = new AssemblyLoadContext("plugin", isCollectible: true); var asm = alc.LoadFromAssemblyPath(path); // ... alc.Unload(); // 参照が切れれば GC で回収されるただし
AssemblyLoadContextも
**「参照が 1 つでも残っていればアンロードされない」**ため、
AppDomain ほど確実ではない。
確実に捨てたいなら、プロセスを分けるのが現在の定石である。
補足(
AppDomain型自体は今も使う): 型が廃止されたわけではなく、
次のメンバーは .NET Core 以降でも有効で、実務でよく使われる。
メンバー 用途 AppDomain.CurrentDomain.BaseDirectory実行ディレクトリの取得 UnhandledException未処理例外のログ出力 ProcessExit終了時の後始末 GetAssemblies()読み込み済みアセンブリの列挙 一方、
CreateDomain/Unload/SetDataなどの
分離に関わる API は使えない。
- アプリケーション ドメイン (.NET Framework)
https://learn.microsoft.com/ja-jp/dotnet/framework/app-domains/application-domains - .NET Core での AppDomain の変更点
https://learn.microsoft.com/ja-jp/dotnet/core/porting/net-framework-tech-unavailable#application-domains - AssemblyLoadContext を使用してアセンブリを読み込む・アンロードする
https://learn.microsoft.com/ja-jp/dotnet/standard/assembly/unloadability
Tags: 移行, .NET開発
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。