为什么.NET框架会锁定dll?

时间:2014-05-07 21:21:13

标签: c# .net

由于DLL被加载到内存中,有没有理由为什么参考dll必须被正在运行的进程锁定?除了将dll复制到临时文件夹并从那里加载之外,还有什么方法可以解决锁定问题吗?

1 个答案:

答案 0 :(得分:21)

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等高可用性应用程序