【问题标题】:When can two .NET processes share DLL memory?两个 .NET 进程何时可以共享 DLL 内存?
【发布时间】:2013-05-23 19:23:22
【问题描述】:

我有两个引用同一个类库的 ASP.NET 网站。目前,我们使用两个类库副本发布该站点。这会浪费内存吗?操作系统是否知道文件的两个副本是相同的,因此可以为 DLL 的代码部分共享内存?如果我将它复制到 GAC 或另一个共享位置,使其只有一个物理文件,它会映射更少的总内存吗?

【问题讨论】:

  • 如果您担心这一点,那么可能还有其他问题。
  • 如果您问这样的问题,dll 的大小是多少?如果你在谈论 asp.net,你为什么要标记 Windows?
  • @Uzzy 它实际上共享了许多 dll,价值数百兆。为了这个问题,我正在简化。 Windows,因为它主要是一个通用的 Windows 问题,但我包括了 .NET 部分以防它影响答案。

标签: .net windows dll memory-mapping


【解决方案1】:

这个问题的前提是错误的,ASP.NET DLL 不包含任何代码。只是数据、IL 和程序集清单。抖动从 IL 生成机器代码,该代码进入 AppDomain 的加载程序堆。进程的私有字节,不共享。

获取从 IL 生成的机器代码的一份副本是可能的,您必须运行 Ngen.exe。它预编译 IL 并生成本地 DLL,即存储在 GAC 子目录中的 .ni.dll。该代码只能与 RAM 中的一个副本共享。

【讨论】:

  • 在首选基地址加载也是难题的一个重要部分。 msdn.microsoft.com/en-us/magazine/cc163610.aspx#S4 在较新版本的 Windows 中实现并强烈推荐用于网络代码的 Address-Space-Layout-Randomization 会干扰它。
  • @Hans Passant:在 Process Explorer 中,我确实看到我的 .NET DLL 从临时 ASP.NET DLL 路径加载了多次,由虚拟路径分隔,并且加载了非零(通常很重要) WS 可共享字节和 0 WS 共享字节。这对我来说意味着如果我把它塞进 GAC,我可以分享其中的一些东西。如果我先对它们进行 NGen,也许会更多?
  • 正如我所解释的,如果您想要共享字节的非零值,那么您需要运行 ngen.exe 并重试。
  • 我会试试看,但是如果 .NET dll 是所有数据,为什么还有任何“可共享”字节?
【解决方案2】:

进程和应用程序域必须将其加载到内存中才能正常运行。应用程序域和进程被沙盒化。

【讨论】:

  • 是的,但是操作系统可以共享一些常用加载的 DLL 的只读部分。我想知道是否/如何确保我利用它。
猜你喜欢
  • 2013-07-16
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2012-01-01
相关资源
最近更新 更多