无法在C#中卸载单个程序集的原因是什么

时间:2012-02-22 07:24:55

标签: c# .net assemblies clr appdomain

在C#中(或者通常在.NET中)无法从内存中卸载单个程序集。 卸载只能在AppDomain级别进行。

我想知道这个设计背后有什么原因?其他语言支持此功能(我认为是C ++)

1 个答案:

答案 0 :(得分:4)

Here is an MSDN blog post列出了一些原因。主要问题是:

  

首先,您在app域中运行该代码(呃!)。这意味着可能存在呼叫站点和调用堆栈,其中包含期望继续工作的地址。你有没有得到一个访问冲突,你的EIP指向0x ????????这是一个例子,有人释放了一个DLL,页面被内存系统取消映射,然后你试图分支到它。当您有引用计数错误并且进行接口方法调用时,这通常发生在COM中。我们无法承受托管代码的损失。我们必须保证我们知道您正在执行的所有代码,并且它是类型安全且可验证的。这意味着显式跟踪可能使用该代码的任何内容,包括GC对象和COM互操作包装器。今天围绕app域边界处理此跟踪。在装配级跟踪它变得非常昂贵。

我将用更高级别的语言对此进行总结:

基本上,如果您只是删除可执行代码,那么在非托管级别上出错就会出错。您将编译指向不再存在的其他已编译代码的代码,因此您的代码将跳转到无效区域,并且可能包含任意数据。

这在托管代码中是不可接受的,因为事情本身是安全的并且有一些保证。其中一个保证是你的代码不能执行任意内存部分。

要正确处理这个问题,你必须更密切地跟踪更多的事情,这将是一个很大的开销。另一种方法是仅在appdomain边界跟踪这些事情,这就是所做的。