.NET JIT编译的代码在哪里缓存?

smw*_*dia 46 .net c# clr jit

.NET程序首先编译为MSIL代码.执行时,JIT编译器会将其编译为本机机器代码.

我想知道:

这些JIT编译的机器代码存储在哪里?它只存储在进程的地址空间中吗?但是由于程序的第二次启动比第一次快得多,我认为即使在执行完成之后,这个本机代码也必须存储在磁盘上.但是哪里?

Han*_*ant 73

记忆.它可以被缓存,这是ngen.exe的工作.它生成一个.ni.dll版本的程序集,包含机器代码并存储在GAC中.然后绕过JIT步骤自动加载.

但这与你第二次启动程序的原因没什么关系.你第一次有一个所谓的"冷启动".这完全由在硬盘驱动器上查找DLL所花费的时间占主导地位.第二次热启动时,DLL已在文件系统缓存中可用.

磁盘很慢.SSD是一个明显的解决方案.

Fwiw:这不是托管代码专有的问题.具有大量DLL的大型非托管程序也有它.大多数开发机器上的两个规范示例是Microsoft Office和Acrobat Reader.他们作弊.安装后,他们在Run注册表项或Startup文件夹中放置一个"优化器".这些优化器所做的就是加载主程序使用的所有DLL,然后退出.这会使文件系统缓存占主导地位,当用户随后使用该程序时,由于其热启动很快,它将快速启动.

就个人而言,我觉得这非常烦人.因为他们真正做的是减慢我登录后可能要启动的任何其他程序.这很少是Office或Acrobat.我强调要删除这些优化器,如果有必要,当一个blasted更新将它重新放回时.

你也可以使用这个技巧,但请负责任地使用它.

  • Vista和Windows 7内置了这个DLL缓存技巧,因此您不再需要制作"app accelerator".Superfetch记录您最常使用的应用程序,并在启动后读取这些文件.它比加速器应用程序更好,因为它关注当前的内存使用和实际的应用程序使用. (17认同)

Tim*_*oyd 11

正如其他人所指出的那样,代码在你的情况下基于每个进程进行JIT,而不是缓存 - 你在第二次加载时看到的加速是程序集的OS磁盘缓存(即内存中).

但是,虽然框架的桌面\服务器版本中没有缓存(除了OS磁盘缓存),但是在另一个版本的框架中缓存了JIT的机器代码.

有趣的是.Net Compact Framework(用于Windows Phone 7的NETCF)中发生的事情.最近的进展看到在JIT代码确实被缓存的进程之间共享一些JIT框架代码.这主要是为了在诸如移动电话的受限设备中实现更好的性能(加载时间和存储器使用).

因此,在回答问题时,在CLR的桌面\服务器版本中没有JIT代码的直接框架缓存,但是最新版本的紧凑框架即NETCF.

参考:我们相信分享

http://blogs.msdn.com/b/abhinaba/archive/2010/04/28/we-believe-in-sharing.aspx


Sam*_*Sam 7

每次首次执行方法时,JIT编译的机器代码都会缓存在每个方法的内存中.我不认为它曾被缓存到磁盘上.

您可能会发现第二次加载过程更快,因为Windows在第一次运行时缓存(在内存中)您的进程使用的文件(dll,资源等).在第二次运行时,不需要转到磁盘,这可能是在第一次运行时完成的.

您可以通过运行NGen.exe来实际预编译您的体系结构的机器代码来确认这一点,并比较第一次和第二次运行的性能.我敢打赌,由于操作系统中的缓存,第二次运行仍然会更快.