【问题标题】:What are app domains used for?应用程序域用于什么?
【发布时间】:2011-05-19 23:39:53
【问题描述】:

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

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

特别是:

  • 我了解一个域中的故障或致命异常不会影响在同一进程中运行的其他应用程序域 - 这是否也适用于非托管/C++ 异常,甚至可能是堆损坏或其他内存问题。
  • AppDomain 间通信如何工作?
  • 使用 AppDomain 与简单地生成多个进程有何不同?

【问题讨论】:

  • 我建议将这个问题分成至少 2 个 - 一个关于异常,一个关于 AppDomain 间通信。

标签: c# c++ appdomain


【解决方案1】:

为了解决内存共享和稳定性问题,运行完全独立的代码模块的应用程序域隔离策略与其说是现实,不如说是一种幻想。

【讨论】:

  • 不,我没有,但现在我做到了
【解决方案2】:

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

回答您的观点/问题:

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

  • AppDomain 之间的通信是使用 .NET 远程处理来强制隔离的。这可以通过引用编组或值语义编组,在性能和灵活性之间进行权衡。

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

【讨论】:

    【解决方案3】:

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

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

    顺便说一句,CLR 的任何功能都无法保护破坏堆的本机代码。最终,CLR 是本地实现的并共享相同的地址空间。因此,该过程中的本机代码可以在 CLR 的内部各处乱涂乱画!隔离表现不佳(即大多数)本机代码的唯一方法是在操作系统级别进行实际进程隔离。启动多个 .exe 进程并让它们通过某种 IPC 机制进行通信。

    【讨论】:

    • 我应该澄清一下 - 我只是指我的自己的本机代码!
    【解决方案4】:

    实际上,AppDomain 中的严重故障不会影响其他人,这不是正确的。在坏事的情况下,最好把它拆掉的过程。有几个例子,但老实说我没有记住它们 - 我只是在心里记下了“坏事 = 拆除过程(检查)”

    AppDomain的好处:

    • 您可以卸载AppDomain;我将它用于根据数据库中的数据自行编译(元编程)的系统 - 它可以启动一个 appdomain 来托管新的 dll 一段时间,然后在新数据可用(并构建)时安全地交换它
    • AppDomains 之间的通信相对便宜。 IMO 这是我高兴唯一一次使用远程处理(尽管您仍然需要真正小心边界上的对象以避免它们之间的引用溢出,从而导致“ fusion" 将额外的 dll 加载到主 AppDomain,从而导致泄漏) - 这也很容易 - 只需 CreateInstanceAndUnwrap(或者是 CreateInstanceFromAndUnwrap?)。
    • vs 产生一个额外的进程 - 你可以选择任何一种方式;但是你不需要另一个 exe 来完成AppDomain 的工作,而且设置你需要的任何通讯都容易得多

    【讨论】:

      【解决方案5】:

      我并没有声称自己是 AppDomains 方面的专家,所以我的回答不会包罗万象。也许我应该首先链接到一个确实有点像专家的人的精彩介绍,看起来像covering all aspects of AppDomain usage

      我自己与 AppDomains 的主要接触是在安全领域。在那里,我发现的最大优势是能够以高度信任的方式运行主域,从而生成多个具有受限权限的子域。通过以高度信任的方式限制权限,在不使用应用程序域的情况下,受限制的进程仍然有权提升自己的权限。

      【讨论】:

        猜你喜欢
        • 2010-11-08
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 2018-03-27
        相关资源
        最近更新 更多