CLR via C# 读书笔记1-5

来源:互联网 发布:sql not in怎么用 编辑:程序博客网 时间:2024/05/17 07:22

本地代码生成器: NGen.exe

NGen.exe 能把 IL 代码变异为本地代码,这使得在运行时 CLR 的 JIT 编译器不需要在运行时编译 IL 代码从而提高运行效率。NGen.exe 适用以下两个场景:
■ 提高程序的启动速度
■ 降低程序的 working set (当你的程序集会被多个进程适用的时候) 
NGen.exe 有这个作用的原因是它把编译后的本地代码存放在一个独立文件中,而这个文件可以被内存映射到多个进程的地址空间中,这些进程可以共用一份代码,而不需要各自搞一份。

NGen.exe 把生成的本地代码文件存放在类似 %SystemRoot%\Assembly\NativeImages_v4.0.#####_64 的目录中,目录名包含了 CLR 的版本号以及 32-bit 或 64-bit 信息。每当 CLR 载入一个程序集时,他总是检查是否有对应版本的被 NGen 过的本地文件存在,如果不存在 CLR JIT 编译器照常介入,反之 CLR 使用这些变异过的代码。

但是NGen 也有以下的缺点:
■ NGen 生成的文件无法脱离包含 IL 文件独立运行,因为他需要metadata。另外某些情况下(见后文) CLR 无法使用 NGen 生成的文件,JIT 编译器还是需要 IL 代码。
■ NGen 生成后文件后,原程序或环境发生了变更,造成不同步。例如:

• CLR 版本:升级或打补丁
• CPU 类型:硬件升级
• Windows 操作系统版本:升级或打补丁
• 程序集标示号 ssembly’s identity module version ID (MVID):重新编译
• 参照的程序集版本标示:参照程序集被重新编译
• 安全:安全策略变更(比如: declarative inheritance, declarative ink-time, SkipVerification, 或 UnmanagedCode 权限)

小提示: NGen.exe 可以运行在 update 模式中,在这种模式下,已经被 NGen 处理过的文件会被及时更新,并保持同步。

之前的文章中提到过NGen.exe 因为无法获晓代码运行时的系统环境,所以无法做到 JIT compiler 那样生成高优化率的指令,有些情况下它生成的代码要比通过 JIT 编译器执行的方式慢5%左右。

通常来说 server 端的程序,适用 NGen.exe 意义不大,因为仅仅首次的客户请求得到优化,而且由于大多数server 端的程序仅一个实例,所以降低 working set 消耗的特性也享受不到。
对于客户端的程序,NGen.exe 通常能改善启动时间,降低 working set 消耗。而且如果该程序的所有模块都被 NGen.exe 生成过本地代码, CLR 就完全不需要载入 JIT 编译器。

对于启动时间过长的胖客户端的程序,Microsoft 提供一个名为 Managed Profile Guided Optimization tool (MPGO.exe)。这个工具能分析程序启动时的执行情况,并提供信息给 NGen.exe, 从而使其生成的更好的本地代码,从而进一步提高启动速度。

原创粉丝点击