Explained: Ngen.exe Explained

From Guidance Share
Revision as of 01:00, 18 December 2007 by JD (talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to navigationJump to search

- J.D. Meier, Srinath Vasireddy, Ashish Babbar, Rico Mariani, and Alex Mackman

Ngen.exe Explained

The Native Image Generator utility (Ngen.exe) allows you to run the JIT compiler on your assembly's MSIL to generate native machine code that is cached to disk. After a native image is created for an assembly, the runtime automatically uses that native image each time it runs the assembly. Running Ngen.exe on an assembly potentially allows the assembly to load and execute faster, because it restores code and data structures from the native image cache rather than generating them dynamically.

While this can lead to quicker application startup times and smaller working sets, it does so at the expense of runtime optimization. It is important that you measure your code's performance to see whether Ngen.exe actually provides any benefits for your application.

Startup Time

Ngen.exe can improve startup time due to shared pages and reduced working set. Keep the following points about Ngen.exe and startup time in mind:

  • If all modules are precompiled with Ngen.exe, JIT compilation is not required.
  • I/O for startup can be reduced if the precompiled modules are already (partly) resident.
  • I/O can be increased due to preloading more code than the corresponding MSIL.
  • Startup time can be improved due to reduced or eliminated JIT compilation.
  • Startup time can actually be increased due to additional I/O, if some modules are not precompiled with Ngen.exe and require JIT compilation.

Working Set

Ngen.exe can reduce the total memory utilization for applications that use shared assemblies which are loaded into many application domains in different processes. In the .NET Framework version 1.0 and 1.1, Ngen.exe cannot generate images that can be shared across application domains but does generate images that can be shared across processes. The operating system can share one copy of the natively compiled code across all processes; whereas code that is JIT-compiled cannot be shared across processes because of its dynamic nature.

An application that is completely precompiled with Ngen.exe does not load Mscorjit.dll, which reduces your application's working set by approximately 200 KB. It should be noted that native modules do not contain metadata (in .NET Framework 1.0 and 1.1) and so in precompiled code cases, the CLR must still load both the MSIL version of the assembly along with the precompiled image to gain access to necessary metadata and MSIL. However, the need for MSIL and metadata is minimized when the precompiled image is available, so those sections of the original MSIL image do not contribute nearly as significantly to the working set.

Keep the following points about Ngen.exe and working set in mind:

  • Code that is precompiled with Ngen.exe has the potential to be shared while JIT-compiled code cannot be shared.
  • Shareable pages only help if something actually shares them.
  • Libraries and multi-instance applications can expect some savings due to sharing.
  • Single instance DLL's (those that exist for deployment or factoring reasons) and single instance EXE's will not benefit from improved potential for sharing.

Running Ngen.exe

To run Ngen.exe, use the following command line.

  ngen.exe assemblyname

This generates the native code for the specified assembly. The generated native code is stored in the native image cache, alongside the global assembly cache.

You can delete the assembly from the image cache by running the following command.

  ngen.exe /delete assemblyname.

Related Items

.NET 2.0 Performance Guidelines - Ngen.exe