ので、最近のアセンブリをアンインストールすることができ、.NETのコア3.0を理解する方法を尋ねたので、私は、グループ内のこの単純な分析を書きました。
それは本当にほんの少しの時間だったので、この記事では、理解するための公式ドキュメントで、単純に関連するコードのリストです。
また、書籍「.NETのコア基本的な原理は、」11月に公表することが期待される、出版社は、ドラッグの比較:O.を
リンク
次のように関係者は、アセンブリドキュメントをアンインストールすることができます。
JITコンパイラ後のプログラムにおけるILコードは、コードヒープLoaderAllocatorが管理ネイティブコード、住所次LoaderAllocatorコードに格納されています。
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.hpp
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.cpp
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.inl
ネイティブコードの配布の責任は、ワークスペース管理は、次のアドレスのコードです。
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/codeman.h
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/codeman.cpp
次のようにGCのコードは次のとおりです。
オブジェクトヘッダ(MethodTable)コードは次の通りです。
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/methodtable.h
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/methodtable.inl
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/methodtable.cpp
次のようにAssemblyLoadContextコードは次のとおりです。
分析
.NETのコアでは、我々は(いくつかのデフォルトのAppDomainがありますが)、AssemblyLoadContextによるプログラム管理会議の新しいアプリケーションドメインを作成することはできません。簡単に言えば、AssemblyLoadContextは、このようなアセンブリ依存アセンブリのBとしてアセンブリのセットの依存関係を管理する責任があり、その後、AとBは、ロードされた同じAssemblyLoadContextを使用する必要があります。異なるが、異なるコードヒープを持っている各AssemblyLoadContext LoaderAllocator、関連付けられています。
.NETコア3.0は、ユーザーがAssemblyLoadContextアンロードを作成することを可能にするようになった、JIT生成ネイティブコード、プリコード、およびメタデータの他のタイプを含むアセンブリに割り当てられたリソースを回収即ちAssemblyLoadContext、次のように流れがあります。
- ユーザー作成AssemblyLoadContext(isCollectible =真)
- ユーザーAssemblyLoadContextローダアセンブリA
- ユーザーAssemblyLoadContextローダーアセンブリB
- アセンブリAおよびB型のインスタンスを作成するには、ユーザーのための方法、および実行
- ユーザーはAssemblyLoadContextをアンインストールします
- 例AおよびB型のすべてのアセンブリを待つ.NETのコアは、リリースLoaderAllocatorリソース割当管理AssemblyLoadContext後に回収されています
図を参照することができる(簡略化したプロセスフローである上記の詳細は、公式文書のリンクを見ることができる)と理解。
あなたがAssemblyLoadContextをアンインストールすると、以下のように、コードをLoaderAllocatorするアンリンクは以下のとおりです。
場合GCマークオブジェクト、タグLoaderAllocatorに関連するコードは、(内部gc.cppに)以下つつ。
#define go_through_object_cl(mt,o,size,parm,exp) \
{ \
// 如果对象的 MethodTable 是由可回收的 AssemblyLoadContext 加载的
if (header(o)->Collectible()) \
{ \
// 获取关联的 LoaderAllocator
uint8_t* class_obj = get_class_object (o); \
uint8_t** parm = &class_obj; \
// 标记 LoaderAllocator (根据 exp 的具体逻辑而定)
do {exp} while (false); \
} \
// 如果对象包含引用类型的成员
if (header(o)->ContainsPointers()) \
{ \
go_through_object_nostart(mt,o,size,parm,exp); \
} \
}
// 调用 MethodTable::GetLoaderAllocatorObjectForGC
#define get_class_object(i) GCToEEInterface::GetLoaderAllocatorObjectForGC((Object *)i)
(ドキュメントを再利用される前に公式のロジックを参照してください)関連するコードへのリソースの解放後に回収されLoaderAllocator:
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.cpp#L520
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/appdomain.cpp#L857
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/appdomain.cpp#L817
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/appdomain.hpp#L3086
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/appdomain.cpp#L6240
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/appdomain.cpp#L6283
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.cpp#L88
- https://github.com/dotnet/coreclr/blob/release/3.0/src/vm/loaderallocator.cpp#L1301
説明はここで終了します。記事では、アセンブリとDomainAssemblyについては言及しなかった理由を、彼らは組み立てが重要ではない達成アンロードすることができますので、あなたは、疑問に思うかもしれません、リソースの割り当てと解放はあまりプログラムをアンインストールすることはできません関連するAssemblyLoadContextてLoaderAllocatorの団結があります設定し、それがアセンブリをアンインストールすることであるとしてロードされているコンテキスト(AssemblyLoadContext)。