The term “runtime” can be understood as a collection of services that are required to execute a given compiled unit of code and .NET runtime provides a single ,well defined runtime layer that is shared
Programmers needed to perform a lot of the low-level work (plumbing) like custom security systems, implement error handling,thread handling , application hosting and manage memory.
CLR offer feature-rich set of plumbing services but the primary role is to locate,load and manage .NET objects on your behalf
.NET Framework Class Library support:Contains built-in types and libraries to manage assemblies, memory, security, threading, and other runtime system support
Debugging: Facilities for making it easier to debug code.
Exception management:Allows you to write code to create and handle exceptions.
Execution management:Manages the execution of code
Garbage collection:Automatic memory management and garbage collection
InteropServices: The CLR can interoperate with various kinds of unmanaged code, such as Visual Basic, Visual C++, DLLs, or COM components. Interop allows your managed code to call these unmanaged components.Backward-compatibility with COM and Win32 code.
Just-In-Time (JIT) compilation: An efficiency feature for ensuring that the CLR only compiles code just before it executes
Security:Traditional role-based security support, in addition to Code Access Security (CAS).
Thread management:Allows you to run multiple threads of execution
Type loading: Finds and loads assemblies and types
Type safety: Ensures references match compatible types, which is very useful for reliable and secure code.
How CLR Locate,Load and Manage:
Windows (the OS) will be running at Start; the CLR won’t begin execution until Windows starts it. When an application executes, OS inspects the file to see whether it has a special header to indicate that it is a .NET application. If not, Windows continues to run the application.If an application is for .NET, Windows starts up the CLR and passes the application to the CLR for execution. The CLR loads the executable assembly, finds the entry point, and begins its execution process.
The executable assembly could reference other assemblies, such as dynamic link libraries (DLLs), so the CLR will load those. However, this is on an as-needed basis. An assembly won’t be loaded until the CLR needs access to the assembly’s code. It’s possible that the code in some assemblies won’t be executed, so there isn’t a need to use resources unless absolutely necessary.
As mentioned previously, the C# compiler produces IL as part of an assembly’s output. To execute the code, the CLR must translate the IL to binary code that the operating system understands. This is the responsibility of the JIT compiler.
As its name implies, the JIT compiler only compiles code before the first time that it executes. After the IL is compiled to machine code by the JIT compiler, the CLR holds the compiled code in a working set. The next time that the code must execute, the CLR checks its working set and runs the code directly if it is already compiled. It is possible that the working set could be paged out of memory during program execution, for various reasons that are necessary for efficient operation of the CLR on the particular machine it is running on. If more memory is available than the size of the working set, the CLR can hold on to the code. Additionally, in the case of Web applications where scalability is an issue, the working set can be swapped out due to periodic recycling or heavier load on the server, resulting in additional load time for subsequent requests.
The JIT compiler operates at the method level. If you aren’t familiar with the term method, it is essentially the same as a function or procedure in other languages. Therefore, when the CLR begins execution, the JIT compiler compiles the entry point (the Main method in C#). Each subsequent method is JIT compiled just before execution. If a method being JIT compiled contains calls to methods in another assembly, the CLR loads that assembly (if not already loaded).
This process of checking the working set, JIT compilation, assembly loading, and execution continues until the program ends.
The meaning to you in the CLR execution process is in the form of application design and understanding performance characteristics. In the case of assembly loading, you have some control over when certain code is loaded. For example, if you have code that is seldom used or necessary only in specialized cases, you could separate it into its own DLL, which will keep the CLR from loading it when not in use. Similarly, separating seldomly executed logic into a separate method ensures the code doesn’t JIT until it’s called.
There are three types of JIT compilation in the .NET framework:
Normal JIT Compilation
With the Normal JIT Compiler methods are compiled when called at runtime. After execution this method is stored in the memory and it is commonly referred as “jitted”. No further compilation is required for the same method. Subsequent method calls are accessible directly from the memory cache.
Econo JIT Compilation
It compiles methods when called at runtime and removes them from memory after execution.
It compiles the entire assembly instead of used methods. In .NET languages, this is implemented in Ngen.exe (Native Image Generator). All CIL instructions are compiled to native code before startup. This way the runtime can use native images from the cache instead of invoking the JIT Compiler.