首页 > 代码库 > CLR和JIT
CLR和JIT
在使用IDE进行编译的时候,这个过程具体的叫法是,使用编译器面向CLR来生成代码。对于不同的开发语言,使用的的编译器也不一样,但是生成的代码都一样。
“无论选用哪一个编译器,结果都是一个托管模块。”
托管模块中的中间语言(MSIL),是编译器编译代码时生成的代码,它是与CPU无关的机器语言。当程序运行时,由CLR将中间代码转换为本地CPU指令。因此,任何编译成MSIL的程序都可以再实现CLR的环境上执行。这是.NET Framework具有可移植性的部分原因。
为了执行一个IL指令,首先必须把它转换成本地CPU指令。该处理过程如下:当.NET程序执行时,CLR激活JIT编译器,JIT编译器根据程序中各个部分的需要将MSIL转换成本机代码。
下图展示了一个方法首次调用时发生的事情。
就在Main方法执行前,CLR会检测出Main的代码引用的所有类型。Main方法引用了一个Console类型,这导致CLR分配给Console一个内部结构。在这个内部数据结构中,Console类型定义的每个方法都有一个对应的记录项。每个记录项都容纳了一个地址,根据此地址即可找到方法的实现。
在CLR分配给Console一个内部结构的时候,需要对这个结构进行初始化,CLR将每个记录项都设置成一个函数。这个函数是存在于CLR内部的一个未文档化的函数,JITCompiler。
Main方法首次调用WriteLine时,由于记录项被初始化为JITComplier,JITComplier函数会被调用,调用的结果是,JITComplier将WriteLine方法的IL代码编译成本地CPU指令。然后,本地CPU指令被保存到一个动态分配的内存块中。JITComplier接下来将Console类型定义的WriteLine方法的记录项设置成现在内存块的地址。
一个方法只有在首次调用时才会即时编译,以后对该方法的所有调用都以本地代码的形式运行,无需重新验证IL并把它编译成本地代码。
下图展示了第二次调用WriteLine时发布的事情。