31

So when CLR runtime load a .NET assembly, it compiles it into machine native code. This process is called JITing. NGen is also the process of compiling .NET assembly into native code. I don't understand what is the difference between two?

Lpmat
  • 29
  • 9
palm snow
  • 2,314
  • 4
  • 27
  • 47

5 Answers5

32

The difference is when they occur. The JIT compilation occurs while your program is running. NGen is a typically done at installation time of your program and happens before your program is run. One of the goals of NGen is to remove the JIT penalty from application start up.

JaredPar
  • 673,544
  • 139
  • 1,186
  • 1,421
  • 1
    What is the need of `JIT` at all when we have NGEN? – Imad Jun 01 '17 at 09:20
  • @Imad portability. With NGen you must pre-compile your code for the target system. With JIT it will be compiled (or finished to compile) "on the fly" during execution, which means that you can simply distribute an executable and it'll run anywhere .NET runs. – Mathieu VIALES Jun 03 '19 at 15:57
16

JIT is only done per-method; it doesn't JIT everything... Only the bits you need. Of course this has a small but measurable hit the first time into a method (plus generics etc). NGEN does this work up-front, but must be done on the same platform/architecture etc - essentially that machine. This also means adding it to the GAC etc, which may need higher access.

In many cases, JIT is fine, especially if the app is open for a long time (web servers, for example).

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
9

One very major important difference that has yet to be mentioned is that the native cached images have 'shared code pages', which makes a huge difference in the memory footprint of applications running over Terminal Services or Citrix.

The critical thing to understand about NGEN is that whilst it compiles your code, it also marks the code pages as shareable, so that multiple instances of your application can share parts of the memory space used by the first instance. And that’s really useful if you’re running under Terminal Services.

http://blogs.msdn.com/b/morgan/archive/2009/03/07/developing-net-applications-for-deployment-on-terminal-services-or-citrix.aspx.

This has very important implications for applications being used by multiple users on a single machine as they share memory across processes. This can lead to very strange, difficult to reproduce behaviour and resource management problems if the image caches are not well maintained.

Rabid
  • 2,874
  • 2
  • 22
  • 25
  • 1
    This is also relevant if you run >100 instances of the same worker on the same machine (when processes are preferred over threads due to better isolation/stability). – mbx Jul 03 '13 at 08:08
  • The memory sharing also pertain to web gardens, where the same site loads multiple times in separate W3WP.exe processes. Does JIT still not allow memory sharing? – Brain2000 Feb 20 '14 at 15:45
  • Really, this benefit applies *whenever* you have a lot of processes loading the same binary (executable or not) on the same CLR with the same library versions on the same machine, no matter why it is that you have them. – SamB Dec 08 '15 at 04:27
7

From MSDN...

The Native Image Generator (Ngen.exe) is a tool that improves the performance of managed applications. Ngen.exe creates native images, which are files containing compiled processor-specific machine code, and installs them into the native image cache on the local computer. The runtime can use native images from the cache instead of using the just-in-time (JIT) compiler to compile the original assembly.

http://msdn.microsoft.com/en-us/library/6t9t5wcf(v=VS.100).aspx

Basically NGen allows you pre-JIT and cache the assembly on the local machine. This allows for a faster startup and sometimes execution.

Paulczy
  • 641
  • 3
  • 4
3

Lots of details left out here, but:

Jit isn't quite that... Jit is Just-In-Time, meaning it doesn't get compiled to native code until the code, such as a method, is actually invoked. There are just stubs until then. This will remained cached so that subsequent calls to the method don't re-generate the native code.

NGen does the whole assembly at once. NGen does it all at once so that Jitting isn't required.

vcsjones
  • 128,004
  • 28
  • 283
  • 274