c# - 为什么 .NET Framework 会锁定 dll?

标签 c# .net

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

最佳答案

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

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

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

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

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

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

关于c# - 为什么 .NET Framework 会锁定 dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23528669/

相关文章:

c# - 从 .Contains() 语句中仅获取整个单词

c# - 避免重新编译表达式树以在生成的委托(delegate)中引用不同的目标(自身)

c# - 使用 SQL Server Management Studio 进行数据库查询时遇到问题

c# - 使用 FileUpload 控件一次将多个图像保存到数据库

c# - TDD 新手 : Are there sample applications with tests to show how to do TDD?

.net - 使用绑定(bind)链接连续函数

.net - Mono .NET 框架和 WMI

c# - 使用 Entity Framework 获得结果

c# - 当从 View (Ajax)发送请求时,即使我使用 [FromBody] C#, Controller 中也收​​到 NULL 对象

.net - 跨多个线程管理状态