应用程序域有什么用途?

16

我大致了解什么是AppDomain,但我不完全理解AppDomain的用途。

我参与开发一个大型基于服务器的C# / C++应用程序,我想知道如何使用AppDomains可以提高稳定性/安全性/性能。

特别是:

  • 我了解在一个域中发生故障或致命异常不会影响同一进程中运行的其他应用程序域 - 对于未经处理的/C++异常(甚至堆破坏或其他内存问题)是否也是如此。
  • AppDomain之间如何进行通信?
  • 使用AppDomains与仅生成许多进程有何区别?

1
我建议将这个问题拆分为至少两个部分 - 一个关于异常,另一个关于跨应用程序域通信。 - Mikeon
5个回答

15

一个使用 AppDomain 的基本用例是在托管第三方代码的环境中,因此不仅需要动态加载程序集,还需要卸载它们

没有办法单独卸载程序集。因此,必须创建一个单独的 AppDomain 来容纳可能需要卸载的任何内容。然后在必要时可以丢弃并重新构建整个 AppDomain。

顺便说一下,本地代码破坏堆无法受到 CLR 的任何功能的保护。最终 CLR 是以本地方式实现的,并且共享同一地址空间。因此,进程中的本地代码可以涂鸦 CLR 的内部!隔离行为不良(即大多数)本地代码的唯一方法是在操作系统级别进行实际的过程隔离。启动多个 .exe 进程并通过某些 IPC 机制进行通信。


我应该澄清一下 - 我只是在提到我自己的本地代码! - Daniel Earwicker

6

我强烈推荐 Jeffrey Richter 的 CLR Via C#。特别是第21章详细介绍了AppDomains的目的和用途。

回答您的问题:

  • AppDomains 不能保护您的应用程序免受恶意非托管代码的攻击。如果这是一个问题,您很可能需要使用操作系统提供的完整进程隔离。

  • 使用 .NET remoting 实现 AppDomains 之间的通信以执行隔离。这可以通过按引用或按值语义进行的封送处理来实现,存在性能和灵活性之间的权衡。

  • AppDomains 是在托管代码中实现类似进程隔离的轻量级方式。AppDomains 被认为是轻量级的,因为您可以在单个进程中创建多个 AppDomains,因此它们避免了多个操作系统进程的资源和性能开销。此外,单个线程可以在一个 AppDomain 中执行代码,然后在另一个 AppDomain 中执行代码,因为 Windows 不知道 AppDomains(通过使用 System.AppDomain.CurrentDomain 可以查看)。


4
实际上,并不是说一个AppDomain中的关键失败不会影响其他应用程序域。在出现问题时,最好的选择是关闭该进程。有一些例子,但老实说我没有记住它们 - 我只是做了一个心理笔记“坏事=关闭进程(检查)”。 AppDomain的好处:
  • 您可以卸载AppDomain;我将其用于一个系统,该系统基于来自数据库的数据进行编译(元编程)-它可以启动一个应用程序域来托管新的dll一段时间,然后安全地交换它当新数据可用时(且已构建)。
  • AppDomain之间的通信相对便宜。在我看来,这是唯一让我感到高兴的使用远程调用的时候(尽管您仍然需要非常小心边界上的对象,以避免引用之间的混合,导致“融合”将额外的dll加载到主要的AppDomain中,从而导致泄漏) - 这也很容易 - 只需CreateInstanceAndUnwrap(或者是CreateInstanceFromAndUnwrap?)。
  • 与生成额外进程相比 - 您可以采取任何方式;但是,您不需要为AppDomain工作创建另一个exe,并且设置任何所需的通信也更容易。

1

我并不自称是AppDomains方面的专家,因此我的回答可能不会全面。也许我应该先链接到一个非常好的介绍,由一个看起来有点像专家的人提供,而且似乎涵盖了所有AppDomain使用方面的内容

我自己与AppDomains的主要接触是在安全领域。在那里,我发现最大的优势是能够让主域以高信任级别运行,并产生几个具有受限权限的子域。通过在高信任级别下限制权限,如果没有使用app domains,受限进程仍将具有提升其自身特权的权限。


0

应用程序域分离策略旨在运行完全独立的代码模块,以解决内存共享和稳定性问题,但更像是一种幻觉而非现实。


没有,但现在我会了。 - I Stand With Russia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接