【问题标题】:Why does the .NET framework lock dlls?为什么 .NET 框架会锁定 dll?
【发布时间】:2014-06-25 01:43:40
【问题描述】:

既然 DLL 被加载到内存中,那么引用 dll 是否必须被正在运行的进程锁定?除了将 dll 复制到临时文件夹并从那里加载之外,还有什么方法可以解决锁定问题?

【问题讨论】:

  • 可能是因为您通常不希望正在运行的代码从您下面换出(尤其是因为它还没有经过 JIT 编译)。
  • Windows 和 Windows 应用程序强烈倾向于锁定它们使用或依赖的文件。
  • 如果您发布您的问题,您可能会得到解决方法。
  • @BradleyDotNET:嗯,这很有争议。一般来说,如果没有技术原因阻止某人做某事,那么通常是允许的
  • DLL 不会加载到内存中。并非所有 DLL - 必要的部分都是按需加载的。

标签: c# .net


【解决方案1】:

这是 CLR 创建程序集的内存映射视图以将其映射到内存中的副作用。内存映射文件是 Windows 中的一个低级功能,也在 .NET 4.0 中通过 MemoryMappedFile 类公开。否则,这是 Windows 等按需分页虚拟内存操作系统中的常见功能。

MMF 有很多理想的属性。 “加载”程序集的行为变得非常简单和快速。实际上没有从文件中读取任何内容,它以一种懒惰的方式发生。文件中的每个字节都有一个对应的内存地址。当 CLR 第一次尝试读取程序集元数据或 IL 中的字节时,处理器会触发页面错误,因为该页面在 RAM 中不可用。操作系统通过从磁盘动态读取文件内容来处理它。 CLR 继续运行,就好像什么都没发生一样,它完全不知道发生了什么。

这种懒惰的访问很棒,你不用为你不用的东西买单。因此,如果您需要来自单一类型的单一方法,例如像 Microsoft.VisualBasic.dll 这样的大型程序集,那么您只需为该方法付费。您的程序从不真正读取其他类型的元数据或其他方法的 IL。

还有更多。您也无需为提交内存付费。如果机器上的另一个进程需要 RAM,则可以简单地丢弃包含汇编数据的页面。因为它们可以从文件中重新加载。它们不必由页面文件支持,您可以购买最便宜的虚拟内存。

还有更多。程序集数据总是需要随时从文件中重新加载这一事实也意味着允许任何人修改文件永远不会是正确的。因为这会导致 RAM 中的数据与文件中的数据不匹配。并且因为它无法观察到页面错误,所以从 CLR 的角度来看它是随机变化的。因此,MMF 对文件进行了硬锁定,没有人可以弄乱它。这是一项免费的反恶意软件功能。

还有更多。锁定保证还意味着 CLR 永远不必处理不再与程序集中的 IL 匹配的 jitted 代码。由于程序集中的随机更改几乎不可能与代码执行正确同步,因此实现起来非常困难。这将非常昂贵,方法调用不再是简单的 CALL 指令。而且它不仅限于代码,委托对象的目标方法必须动态解析。非常主要的性能杀手。否则问题已解决,这就是 CLR 支持 AppDomain 概念的原因。卸载 appdomain 会破坏一切、代码和数据。影子复制程序集背后的底层技术,用于 ASP.NET 等高可用性应用程序

【讨论】:

  • Aaaah 内存映射文件。这就说得通了。感谢您提供所有信息!
猜你喜欢
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多