managed code and unmanaged code
cpu不能直接执行IL指令(也许将来可以),但是现在,必须使用CLR中即时(just-in-time,简称JIT)编译器将IL代码转化成本地CPU指令。例如:
static void main(){
Console.WriteLine("hello");
Console.WriteLine("Goodbye");
}
在Main方法执行前,CLR首先检测Main中代码中引用的所有的类型。这会导致CLR分配一个内部的数据结构,该数据结构用于管理多所引用到的类型的 访问。如上代码中Main方法中引用了一个Console类型,CLR将会分配一个单独的内部结构。在这个内部结构结构中,Console类型中的每一个 方法都会有一个对应的条目。每一个条目中将保存有一个实现代码的地址。当数据结构被初始化时,CLR奖把每一个条目设置为CLR内部的一个没有正式纪录的 函数,该函数称为JITCompiler。
When Main makes its first callto WriteLine,the JTICompiler function is called.The JITCompiler function is responsible for compiling method's IL code into native CPU instructions .Because the IL is being compiled "just in time",this component of the CLR is frequently referred to as a JIT compiler.
When called ,the JITCompiler function knowns what method is being callded ande what type defines this method.The JITCompiler function then searches the defining assembly's metadata for the called method's IL.JITCompiler next verifies and compiles the IL code into native CPU instructions. the native CPU instructions are saved in a dynamically allocated block of memory Then,JITCompiler goes back to the type's internal data structure and replaces the address of the CPU instructions with address of the block of memory containing the native CPU instructions.Finally JITCompiler jumps to the code in the memory block.This code is the implementation of the WriteLine method(the version that takes a String parameter).When this code returns,it returns to the code in Main,which continues execution as normal.
Main now calls WriteLine a second time.This time,the code for WriteLine has already been verified and compiled.So the call goes directly to ge block of memory,skipping the JITCompiler function entirely.After the WriteLine method.After the WriteLine method executes
,it returns to Main.
(二)
在托管exe中,一个方法在被首次调用的时候会有一定的性能损失,但在后续的调用中都将以本地的代码做全速的执行,因为本地代码不需要验证和编译。
JIT编译器将本地代码存储于动态内存之中,这意味这当程序关闭的时候,编译生成的本地代码将被丢失。这样,如果我们以后再次运行该应用程序,或者同时运 行该应用程序的两个不同的实例(即位于两个不同的操作系统进程中),JIT编译器需要再次将同样的IL代码编译成本地指令。
For most applications,the performance hit incurrent by JIT compiling isn't significant. Most applications tend to call the same methods over and over agin.These methods will take the performance hit only once while the application executes.Tt's also likely that more time is spent inside the method than calling the method.
static void main(){
Console.WriteLine("hello");
Console.WriteLine("Goodbye");
}
在Main方法执行前,CLR首先检测Main中代码中引用的所有的类型。这会导致CLR分配一个内部的数据结构,该数据结构用于管理多所引用到的类型的 访问。如上代码中Main方法中引用了一个Console类型,CLR将会分配一个单独的内部结构。在这个内部结构结构中,Console类型中的每一个 方法都会有一个对应的条目。每一个条目中将保存有一个实现代码的地址。当数据结构被初始化时,CLR奖把每一个条目设置为CLR内部的一个没有正式纪录的 函数,该函数称为JITCompiler。
When Main makes its first callto WriteLine,the JTICompiler function is called.The JITCompiler function is responsible for compiling method's IL code into native CPU instructions .Because the IL is being compiled "just in time",this component of the CLR is frequently referred to as a JIT compiler.
When called ,the JITCompiler function knowns what method is being callded ande what type defines this method.The JITCompiler function then searches the defining assembly's metadata for the called method's IL.JITCompiler next verifies and compiles the IL code into native CPU instructions. the native CPU instructions are saved in a dynamically allocated block of memory Then,JITCompiler goes back to the type's internal data structure and replaces the address of the CPU instructions with address of the block of memory containing the native CPU instructions.Finally JITCompiler jumps to the code in the memory block.This code is the implementation of the WriteLine method(the version that takes a String parameter).When this code returns,it returns to the code in Main,which continues execution as normal.
Main now calls WriteLine a second time.This time,the code for WriteLine has already been verified and compiled.So the call goes directly to ge block of memory,skipping the JITCompiler function entirely.After the WriteLine method.After the WriteLine method executes
,it returns to Main.
(二)
在托管exe中,一个方法在被首次调用的时候会有一定的性能损失,但在后续的调用中都将以本地的代码做全速的执行,因为本地代码不需要验证和编译。
JIT编译器将本地代码存储于动态内存之中,这意味这当程序关闭的时候,编译生成的本地代码将被丢失。这样,如果我们以后再次运行该应用程序,或者同时运 行该应用程序的两个不同的实例(即位于两个不同的操作系统进程中),JIT编译器需要再次将同样的IL代码编译成本地指令。
For most applications,the performance hit incurrent by JIT compiling isn't significant. Most applications tend to call the same methods over and over agin.These methods will take the performance hit only once while the application executes.Tt's also likely that more time is spent inside the method than calling the method.