【问题标题】:Speed Increase by Using the Global Assembly Cache使用全局程序集缓存提高速度
【发布时间】:2009-06-03 14:59:45
【问题描述】:

如果我有 1000 个 asp.net 网站,每个网站的 /bin 文件夹中有 30 个 DLL。

因此有 30,000 个 DLL。

如果我将一组 DLL 注册到全局程序集缓存中并且每个站点都使用 GAC 中的 DLL,网站/Web 服务器/机器会运行得更快吗?

例如这些网站会共同使用更少的内存吗?

【问题讨论】:

    标签: dll assemblies gac isolation


    【解决方案1】:

    即使程序集位于 GAC 中,它们仍会从那里单独加载到内存中以提供隔离。换句话说,仅仅因为程序集在 GAC 中并不意味着这些副本在 AppDomains 之间共享。我相信 mscorlib(可能还有一些 BCL 程序集)可以在 AppDomains 之间共享,但您或我编写的任何程序集都不会。

    这是一件好事:考虑Cache 类型在 AppDomain 之间共享的含义。

    【讨论】:

    • 可以使用 LoaderOptimizationAttribute 将程序集作为域中性加载。我不确定这样做的含义,但我认为这与跨 AppDomain 共享状态没有任何关系。
    • 正确,但该属性仅在可执行文件的入口点有效,这意味着它与库无关。
    • 啊,好点。但肯定 ASP.NET 已将 CLR 主机配置为允许域中性加载吗?否则,任何在多个项目中使用共享 .DLL 的组织都必须将该 DLL 的单独副本加载到每个 appdomain 的内存中,不是吗?显然每个 appdomain 都需要自己的状态,但是代码本身会被加载两次吗?
    • 是的,代码本身被加载了两次。考虑如果程序集本身是共享的,则任何静态成员都将在 AppDomains 之间共享。想象一下,如果您不仅要关注 AppDomain 中的线程安全性(更不用说安全性),还要关注可能加载相同程序集的任何 AppDomain 中的线程安全性!
    • msdn.microsoft.com/en-us/library/43wc4hhs.aspx 来自 MSDN -“由于需要隔离程序集,域中立程序集对静态数据和方法的访问速度较慢。访问程序集的每个应用程序域必须具有单独的“ /跨度>
    【解决方案2】:

    实际上,@AndrewHare 接受的答案是不正确的。在 GAC 中放置程序集确实有助于减少内存使用。

    Jeffrey Richter(来自与 .NET 团队一起帮助设计 CLR 的 Wintellect)在他的书 CLR via C# 中证实了这一点:

    将程序集安装到 GAC 中有几个好处。 GAC 使许多应用程序能够共享程序集,总体上减少物理内存使用量....

    Tess Ferrandez(来自 Microsoft 的内存和性能专家 - https://blogs.msdn.microsoft.com/tess/2006/04/12/asp-net-memory-you-use-the-same-dll-in-multiple-applications-is-it-really-necessary-to-load-it-multiple-times)也证实了这一点。

    尽可能强名称并安装到全局程序集缓存 (GAC) 中,由多个 ASP.NET 应用程序使用的任何程序集。 这将减少内存消耗。

    我自己也通过在 x64 WebAPI 服务上进行测试(WinDbg、任务管理器和 ProcExplorer)作为示例确认了这一点。您会看到 GAC 应用程序的私有工作集较低。在 NGen 的情况下,您会再次看到私有工作集减少。但是,与基线相比,NGen 的应用程序中的页面错误也大大减少(在我的测试中几乎减少了一半)。我发现 GAC 应用和非 GAC 应用之间的页面错误没有区别。

    请注意,在某些情况下,最好的解决方案是通过将 NGen 的程序集安装到 GAC 中来组合 NGen 和 GAC。这优化了共享程序集的应用程序之间的内存使用,并在应用程序启动时提供了性能提升!

    【讨论】:

      【解决方案3】:

      实际上,这会快得多,特别是如果它们也是 NGEN 的。如果 NGEN 没有将它们放在全局程序集缓存中,那么实际上会减慢速度,因为 CLR 需要执行程序集验证以确保它与本机映像匹配。 CLR 会跳过对 GAC 程序集的检查,而只会加载和使用本机映像。

      NGEN 程序集还具有内存优势,因为它们可以共享代码页。

      您也可以考虑尝试优化 DLL 的基地址,因为如果它们都使用默认值,那么 Windows 需要重新设置 30,000 次!

      这是一篇关于 NGEN 的性能优势的精彩文章。

      http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

      【讨论】:

      • 嗯...是的,通过 NGEN 运行它们并可能更改它们的基地址可能会有所帮助 - 但仅将 1'000 个 DLL 放入 GAC 并没有真正的区别,就我而言可以告诉。
      • 我认为 GAC 程序集的性能改进与该程序集是否是强名称以及是否打开了强名称验证有关。但如果不出意外,CLR 将首先在 GAC 中探测程序集,因此那里可能会有轻微的改进。重大改进来自 NGEN,可能是基地址,尽管我从来没有弄乱基地址。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多