应用程序域的用途是什么?
我大致了解 AppDomain 是什么,但是我不完全了解 AppDomain 的用途。
我参与了一个基于大型服务器的 C# / C++ 应用程序,我想知道如何使用 AppDomains 可以提高稳定性/安全性/性能。
特别是:
- 我知道一个域中的错误或致命异常不会影响同一进程中运行的其他应用程序域 - 这是否也适用于非托管/C++ 异常,甚至可能是堆损坏或其他内存问题。
- AppDomain 间的通信如何进行?
- 使用 AppDomains 与简单地生成许多进程有何不同?
I understand roughly what an AppDomain is, however I don't fully understand the uses for an AppDomain.
I'm involved in a large server based C# / C++ application and I'm wondering how using AppDomains could improve stability / security / performance.
In particular:
- I understand that a fault or fatal exception in one domain does not affect other app domains running in the same process - Does this also hold true for unmanaged / C++ exceptions, possibly even heap corruption or other memory issues.
- How does inter-AppDomain communication work?
- How is using AppDomains different from simply spawning many processes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
AppDomain 的基本用例是在托管第 3 方代码的环境中,因此不仅需要动态加载程序集,还需要卸载它们。
无法单独卸载程序集。因此,您必须创建一个单独的 AppDomain 来容纳可能需要卸载的任何内容。然后,您可以在必要时丢弃并重建整个 AppDomain。
顺便说一句,CLR 的任何功能都无法防止本机代码损坏堆。最终,CLR 是本地实现的并共享相同的地址空间。所以进程中的本机代码可以在 CLR 的内部乱写乱画!隔离行为不良(即大多数)本机代码的唯一方法是操作系统级别的实际进程隔离。启动多个 .exe 进程并让它们通过某种 IPC 机制进行通信。
The basic use case for an AppDomain is in an environment that is hosting 3rd party code, so it will be necessary not just to load assemblies dynamically but also unload them.
There is no way to unload an assembly individually. So you have to create a separate AppDomain to house anything that might need to be unloaded. You can then trash and rebuild the whole AppDomain when necessary.
By the way, native code corrupting the heap cannot be protected against by any feature of the CLR. Ultimately the CLR is implemented natively and shares the same address space. So native code in the process can scribble all over the internals of the CLR! The only way to isolate badly behaved (i.e. most) native code is actual process isolation at the OS level. Launch mutiple .exe processes and have them communicate via some IPC mechanism.
我强烈推荐通过 C# 进行 CLR 作者:杰弗里·里克特。特别是第 21 章详细介绍了 AppDomain 的目的和用途。
回答您的观点/问题:
AppDomains 不会保护您的应用程序免受流氓非托管代码的侵害。如果这是一个问题,您很可能需要使用操作系统提供的完整进程隔离。
AppDomain 之间的通信是使用 .NET 远程处理来执行的,以强制隔离。这可以通过引用编组或按值语义编组,在性能和灵活性之间进行权衡。
AppDomains 是一种在托管代码中实现类似进程隔离的轻量级方法。 AppDomain 被认为是轻量级的,因为您可以在单个进程中创建多个 AppDomain,因此它们避免了多个操作系统进程的资源和性能开销。此外,单个线程可以在一个 AppDomain 中执行代码,然后在另一个 AppDomain 中执行代码,因为 Windows 对 AppDomain 一无所知(通过使用 System.AppDomain.CurrentDomain 来查看这一点)
I highly recommend CLR Via C# by Jeffrey Richter. In particular chapter 21 goes into good detail regarding the purpose and uses of AppDomains.
In answer to your points/question:
AppDomains will not protect your application from rogue unmanaged code. If this is an issue you will most likely need to use full process isolation provided by the OS.
Communication between AppDomains is performed using .NET remoting to enforce isolation. This can be via marshal by reference or marshal by value semantics, with a trade off between performance and flexibility.
AppDomains are a lightweight way of achieving process like isolation within managed code. AppDomains are considered lightweight because you can create multiple AppDomains within a single process and so they avoid the resource and performance overhead multiple OS processes. Also, a single thread can execute code in one AppDomain and then in another AppDomain as Windows knows nothing about AppDomains (see this by using using System.AppDomain.CurrentDomain)
实际上,一个
AppDomain
中的严重故障不会影响其他应用程序域,这是不正确的。如果出现不好的情况,最好的办法就是拆除该过程。有几个例子,但说实话我还没有记住它们 - 我只是在心里记下了“坏事=拆掉进程(检查)”AppDomain
的好处:AppDomain
之间的通信相对便宜。在我看来,这是我唯一一次高兴使用远程处理(尽管您仍然需要非常小心边界上的对象,以避免它们之间的引用泄漏,导致“ fusion” 将额外的 dll 加载到主AppDomain
中,从而导致泄漏) - 这也非常简单 - 只需CreateInstanceAndUnwrap
(或者是CreateInstanceFromAndUnwrap
?)。AppDomain
工作,并且设置您需要的任何通信要容易得多Actually, it is not true that a critical fail in one
AppDomain
can't impact others. In the case of bad things, the best bet it to tear down the process. There are a few examples, but to be honest I haven't memorised them - I simply took a mental note "bad things = tear down process (check)"Benefits of
AppDomain
:AppDomain
; I use this for a system that compiles itself (meta-programming) based on data from the database - it can spin up an appdomain to host the new dll for a while, and then swap it safely when new data is available (and built)AppDomain
s are relatively cheap. IMO this is the only time I am happy to use remoting (although you still need to be really careful about the objects on the boundary to avoid bleeding references between them, causing "fusion" to load extra dlls into the primaryAppDomain
, causing a leak) - it is really easy too - justCreateInstanceAndUnwrap
(or is itCreateInstanceFromAndUnwrap
?).AppDomain
work, and it is much easier to set up any comms that you need我并不声称自己是 AppDomains 方面的专家,因此我的回答不会包罗万象。也许我应该首先链接到一个确实有点像专家的人的精彩介绍,看起来就像涵盖 AppDomain 使用的各个方面。
我自己与 AppDomains 的主要接触是在安全领域。在那里,我发现的最大优势是能够让主域在高信任度下运行,从而生成多个具有受限权限的子域。通过限制高度信任的权限,在不使用应用程序域的情况下,受限制的进程仍然有权提升自己的权限。
I'm not claiming to be an expert on AppDomains, so my answer will not be all-encompassing. Perhaps I should start off by linking to a great introduction by a guy who does come off as somewhat an expert, and what does seem like covering all aspects of AppDomain usage.
My own main encounter with AppDomains has been in the security field. There, the greatest advantage I've found has been the ability to have a master domain run in high trust spawning several child domains with restricted permissions. By restricting permissions in high trust, without the use of app domains, the restricted processes would still have the permission to elevate their own privileges.
为了解决内存共享和稳定性问题而运行完全独立的代码模块的应用程序域隔离策略更多的是一种幻想而不是现实。
App Domain segregation strategy for running completely independent code modules, in order to address memory sharing and stability concerns, is more of an illusion than a reality.