• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

CLR via C# 3 读书笔记(5):第1章 CLR执行模型 — 1.5 本地代码生成器工具:NGen.ex ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

NGen.exe工具(本机映像生成器)随.NET Framework一起发布,用来在客户机上安装应用程序时,将IL代码编译为本地代码。由于代码在安装时已经编译了,运行时JIT编译器就无需再次编译,这可以提升程序性能。

  • 缩短程序启动时间。
  • 减少程序工作区大小。NGen.exe将编译的本地代码保存为一个单独的文件,该文件可同时被多进程地址空间进行内存映射,每个进程不需要单独的拷贝。

当安装程序对应用程序或单独的程序集调用NGen.exe时,应用程序所用的程序集或那个指定的程序集的IL代码将被编译为本地代码。NGen.exe将生成一个仅包含本地代码的新的程序集文件(不包含IL代码)。这个新的文件位于类似C:\Windows\Assembly\NativeImages_v4.0.#####_64这样的目录下。目录名称包含CLR版本,以及本地代码编译为x86、x64还是Itanium。

现在,当CLR加载程序集文件时,会先查找是否存在相应的NGen后的本地文件。如果没找到,CLR即时编译IL代码。如果存在,CLR将使用已存在的本地文件,并且在运行时不再需要编译文件中的方法。

表面上开来,你好像即得到了托管代码的好处(垃圾回收、验证、类型安全等),又避免了性能问题(JIT编译),似乎很棒。但其实有很多潜在问题:

  • 没有代码保护。使用NGen并非意味着可以不发布包含IL代码的文件。
  • NGen的文件可以不同步。当CLR加载NGen文件时,会比较前期编译的代码和当前执行环境的诸多特征。如果任何一个特征不相符,就不使用NGen文件,取而代之的仍然是普通的JIT编译过程。必须匹配的特征如下:
    • CLR版本:打补丁时会改变。
    • CPU类型:升级硬件时会改变。
    • 操作系统版本:更新SP包时会改变。
    • 程序集的identity module version ID(MVID):重新编译时
    • 引用的程序集的版本ID:重新编译引用的程序集时
    • 安全:撤销许可时
  • 所以必须在更新模式时时对所有程序集再次运行NGen.exe。如更新.NET Framework补丁时,补丁包安装程序将自动运行NGen.exe,使NGen.exe文件与CLR版本保持同步。
  • 运行时性能低下:NGen在编译代码时并不能像JIT编译器那样对执行环境做许多假设。因此NGen生成的是劣等代码。如,NGen无法优化CPU指令的使用;它还添加了对静态字段的间接访问,因为静态字体在运行时之前没有实际地址。NGen在各处插入调用构造函数的代码,因为它不知道代码执行的顺序以及构造函数是否访问过。NGen编译的程序性能通常会损失5%。因此如果你考虑使用NGen改善程序性能,应该比较一下NGen和非NGen版本的性能。

因此,慎用NGen。

对于服务器端应应用,NGen几乎没有意义,因为只有第一次请求会损害性能。而且对于服务器应用,只需要一个代码实例,不需要工作组。NGen生成的映像不能跨应用程序域。类似ASP.NET这种需要跨应用程序域的程序集就没必要NGen了。

对于客户端应用,NGen会改善程序启动时的性能减少工作组,如果程序集同时用于多个程序的话。即使程序集没有用于多个程序,NGen仍然能够改善工作组。此外,如果所有客户端程序都使用NGen,CLR就没有必要加载JIT编译器,这能进一步减少工作组。当然只要一个程序集没有使用NGen或者不能使用NGen,JIT编译器都将加载,并增加工作组。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# MVC 批量修改商品数据发布时间:2022-07-14
下一篇:
C# using 三种使用方式发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap