在 .NET Core 中我们不能新建 AppDomain (尽管有默认的几个 AppDomain),程序集会通过 AssemblyLoadContext 管理。简单的来说,AssemblyLoadContext 负责管理有依赖关系的一组程序集,例如程序集 A 依赖程序集 B,那么 A 和 B 需要使用同一个 AssemblyLoadContext 加载。每个 AssemblyLoadContext 都会关联不同的 LoaderAllocator,也就是拥有不同的 Code Heap。
.NET Core 3.0 开始允许卸载用户创建的 AssemblyLoadContext ,也就是回收 AssemblyLoadContext 为程序集分配的各种资源,包括 JIT 生成的原生代码,PreCode,类型元数据等,流程大致如下:
可以参考下图理解 (这是经过简化的流程,详细流程可以看前面给出的官方说明文档链接):
卸载 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)
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!