What is NGen?
A tool comes with .NET framework, which is used to generate native image of a managed assembly.
The managed assemblies (.dll and .exe) contain IL code that are not understandable by native operation system. When executing the managed application, JIT compiler compiles the IL code into native code. This would require some amount of memory for JIT compiler and the application takes some time on start-up.
NGen provides pre-compilation option so that you can compile your application IL code into native code one shot before starting the application itself. The .NET framework libraries, Paint.NET are some applications use NGen.
How it works?
NGen invokes “Compilation Worker” when you give a managed assembly for native code generation. Compilation Worker loads runtime and uses JIT compiler to create native code. It places the JIT generated native code into the assembly cache in a file with name “YourAssemblyName.ni.dll”. This file is generally called as “native image”. The cache folder path is %Windows%\Assembly\NativeImages_v2.0.50727_32. When you run the application, CLR finds the native image of an assembly and executes it, if the assembly exists on cache; otherwise it does normal path.
Advantages
- Lesser application start-up time. Since compilation and module load are not required for native image.
- Sharable. The NGen generated native image contains memory base address details so that once an assembly is loaded into memory it can directly be usable by another applications those require the specific assembly.
Is It Value-Add?
The advantages make us very happy after all we are the guys working behind virtual machines a.k.a CLR. However, you cannot write a single rule of thumb for NGen usage. Using NGen is varied based on the situation or requirement. One rule of thumb for NGen would be:
Do not use native images for server side applications. The assemblies for a server side applications are loaded and JITted only once at the first time of request. For succeeding requests, the JIT compiled codes are executed. So, there is no benefit using NGen on server side application.
Consider the following for client side applications before decide to use NGen:
- NGen is not so smart to load native image for a managed assembly. CLR gets fail to load native image, if it finds assembly version, CPU and CLR version mismatch.
- The native code generated using NGen are not purely optimized for underlying environment in compare with JIT compilation. JIT compiler generates more optimized code for the target environment.
- NGen generated codes typically contain base address which may results more process consumption if the particular base address is already claimed by another application. Despite C# compiler’s “/baseaddress” option may fix this issue, however a smart way need to be applied which is most of the time not considered. Simply, sharable nature of native image is not consistent.
So, “Think twice before NGen” for client side applications.