1.5 The Native Code Generator Tool: NGen.exe 本地代码生成工具NGen.exe

 

NGen.exe是和.NET框架绑定在一起的。当用户的机器上安装了一个应用程序,NGen.exe将会把IL代码编译成本机代码。因为代码是在安装的时候编译的,CLRJIT编译器不需要在运行时编译IL代码,而且这回提高应用程序的性能。

 

下面是NGen.exe使用的两个情景

  ■ 提高应用程序的启动时间  运行NGen.exe能够提高启动时间,是因为在运行时之前代码已经被编译成本地代码,运行时不需要再编译。

  ■ 减少应用程序的工作区 你可能知道一个程序集会在多个进程中同时加载,在这个程序集中使用NGen.exe能够减少应用程序的工作区。原因是NGen.exe会编译IL成本地代码,并把输出保存在一个独立的文件中。这个文件能够通过内存映射到多进程的地址空间,并允许代码共享。

 

如果一个安装程序在一个应用程序或者是程序集里启动了NGen.exe,应用程序里的所有程序集或者是一个单独的程序集会将IL编译成本地代码。一个新的程序集文件只包含由NGen.exe创建的本地代码。这个新的文件会放在一个名为C:\Windows\Assembly\NativeImages_v4.0.#####_64的文件夹下。文件夹的名字包括CLR的版本,以及本地代码是为32位或是64位机编译的信息。

 

现在,当CLR加载一个程序集文件,CLR会查看是否存在NGen的本地文件。如果没有,CLR JIT 会像平时一个编译IL代码。但是,如果存在,CLR会使用本地文件中编译过的代码,而且文件中的方法在运行时不会再编译。

 

表面上,这听起来不错。看起来你似乎获得了托管代码的所有好处(GC垃圾回收,verification验证,type safety类型安全等等),而且还不会有托管代码的性能问题。但是,事实上它不像它看起来的那么美好。这里有一些关于NGen'd文件的潜在问题:

  ■ 没有只是产权保护

  ■ NGen'd 可能会不同步

  ■ 执行时性能差  编译代码的时候NGen不能像JIT编译器那样对执行环境做很多假设,这也导致NGen 生产低效的代码。

 

就上面列出的几个问题,你应该仔细想想是否使用NGen.exe。对于服务端的应用程序,NGen.exe的作用微乎其微,因为只有第一个客户端请求才会造成一些性能损失;以后的客户端请求能够全速运行。另外,对于大多数的服务应用程序,代码的一个实例就够了。在说了,NGen'd图形不能在应用程序域中传递,所以也没有必要在跨应用程序域的情景下使用(比如ASP.NET)

 

对于客户端应用程序,如果程序集是被多个应用程序同时使用,NGen.exe可能对提高启动时间或减少工作区有点用处。甚至有种情况,如果一个程序集不是被多个应用程序使用,NGen.ing一个程序集会提高工作区。