Where is the .NET JIT code cached?

The .NET program is first compiled into MSIL code. When it is executed, the JIT compiler will compile it into native machine code.

I am wondering:

Where are these JIT-compiled machine codes stored? Is it stored only in the process address space? But since the second launch of the program is much faster than the first time, I think that this native code should be saved on disk somewhere even after completion of execution. But where?

+43
c # clr jit
Jul 21 '10 at 1:18
source share
6 answers

Memory. It can be cached by ngen.exe to work. It generates a version of the .ni.dll assembly, which contains machine code and is stored in the GAC. Which automatically loads after that, bypassing the JIT step.

But this has little to do with why your program runs faster the second time. The first time you have a so-called cold start. Which is completely dominated by the time spent searching for DLLs on the hard drive. The second time you started a warm start, the DLLs are already available in the file system cache.

Drives are slow. SSD is an obvious fix.

Fwiw: This is not an issue that is exclusive to managed code. Large unmanaged programs with lots of DLLs have it too. Two canonical examples found on most development machines are Microsoft Office and Acrobat Reader. They are cheating. During installation, they put the "optimizer" in the "Run the registry key" section or the "Startup" folder. All these optimizers do is download all the DLL files that the main program uses and then exit. This means that the file system cache, when the user subsequently uses the program, starts quickly, as his hot start is fast.

Personally, I find this extremely annoying. Because what they really do slows down any other program that I might want to start after I log in. It is rarely Office or Acrobat. I do this to remove these optimizers, if necessary, when the update is exploded.

You can also use this trick, but use it responsibly.

+68
Jul 21 2018-10-21T00:
source share
β€” -

As others have pointed out, the JIT'd code for each process in your case is not cached - the acceleration that you observe during the second boot is the caching of the OS disk (i.e. in memory) nodes.

However, although caching (except for caching the OS disk) is not available in the desktop / server version of the framework, JIT'd caching of machine code is performed in another version of the framework.

I wonder what happens in the .Net Compact Framework (NETCF for Windows Phone 7). Recent advances show the sharing of some JIT'd code between processes in which JIT'd code is actually cached. This was mainly done to improve performance (load time and memory usage) in limited devices such as mobile phones.

Thus, in response to a question, there is no direct caching of the JIT'd code structure in the desktop \ server version of the CLR, but it will be in the latest version of the compact structure, i.e. NETCF.

Link: we believe in sharing

http://blogs.msdn.com/b/abhinaba/archive/2010/04/28/we-believe-in-sharing.aspx

+10
Jul 21 2018-10-10T00:
source share

Compiled JIT machine code is cached in memory for each method, each time the method is executed for the first time. I do not think that it is always cached to disk.

You may find that this process loads faster the second time, because in the first mode Windows cached (in memory) the files used by your process (DLL, resources, etc.). In the second run, there is no need to switch to the disk, where it was possible at the first start.

You can confirm this by running NGen.exe to actually precompile the machine code for your architecture and compare the performance of the first and second runs. My bet is that the second launch will still be faster, due to caching in the OS.

+6
Jul 21 '10 at 1:27
source share

In short, the IL is compiled by JIT for each program call and is supported on the code pages of the process address space. See Chapter 1 Richter for a large coverage of the .NET runtime model.

+2
Jul 21 '10 at 1:23
source share

I believe that compiled JIT code is never stored or exchanged memory. The performance improvement that you perceive during the second execution of the assembly is due to the fact that the dependent assemblies are already in the memory or disk cache.

+1
Jul 21 '10 at 1:23
source share

Yes, NGEN.EXE will put the JIT-compiled version of the .NET executable in the GAC, even if there is no MSIL version. I tried this, but to no avail. I believe that if the original version of MSIL is also not in the GAC and is downloaded from there, the JIT version in the GAC will not be used. I also find that JIT compilations on the fly (non-NGEN) are never cached; they occupy the process only memory.

I believe this from reading an MS document and from various experiments. I would welcome either confirmation or refutation of my claims from those who know.

+1
Sep 12 '13 at 16:30
source share



All Articles