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

发布于 2025-01-08 02:46:07 字数 109 浏览 0 评论 0原文

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

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

In C# (or maybe in .NET in general) individual assemblies cannot be unloaded from memory.
Unloading can only occur at the AppDomain level.

I am wondering what are there reasons behind this design? Other languages support this feature (C++ i think)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日落 2025-01-15 02:46:07

这是一篇 MSDN 博客文章,列出了一些原因为什么不呢。主要问题是:

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

我将用更高级的语言来总结这一点:

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

这在托管代码中是不可接受的,因为事物应该是安全的并且有一些保证。这些保证之一是您的代码无法执行内存的任意部分。

为了正确处理这个问题,您必须更密切地跟踪更多的事情,这将是一个很大的开销。另一种方法是仅在应用程序域边界跟踪这些内容,这就是所做的事情。

Here is an MSDN blog post listing some reasons why not. The main issue is:

First off, you are running that code in the app domain (duh!). That means there are potentially call sites and call stacks with addresses in them that are expecting to keep working. Have you ever gotten an access violation where your EIP points to 0x???????? That is an example where someone freed up a DLL, the pages got unmapped by the memory system, and then you tried to branch to it. This typically happens in COM when you have a ref counting error and you make an interface method call. We cannot afford to be as lose with managed code. We must guarantee we know all of the code you are executing and that it is type safe and verifiable. That means explicit tracking of anything that could be using that code, including GC objects and COM interop wrappers. This tracking is handled today around an app domain boundary. Tracking it at the assembly level becomes quite expensive.

I'll summarise this in higher-level language:

Basically, things that go wrong if you simply delete executable code go wrong on the unmanaged level. You would have compiled code that points to other compiled code that is no longer there, so your code would jump into an area that is invalid, and possibly contains arbitrary data.

This is unacceptable in managed code, because things are meant to be safe and have some guarantees around them. One of these guarantees is that your code can't execute arbitrary sections of memory.

To handle this issue properly you'd have to track many more things more closely, and this would be a large overhead. The alternative is to only track these things at appdomain boundaries, which is what is done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文