c# 应用程序运行环境
很多人只知道c# 应用程序运行 必须有CLR(公共语言运行时)和.net框架的支持,但不知道为啥需要?
其实很简单,因为.exe只是IL指令,CIL(公共中间语言),目前的CPU还不能直接执行IL指令,但将来的CPU也许会具有这种能力。执行exe它的IL代码还必须首先被转换成为本地CPU指令,这属于CLR中即时编译器的工作。总所周知,程序入口点是Main函数,在程序执行之前,CLR检测Main中代码所引用到的所有类型,分配多个内部的数据结构,一个类对应一个数据结构,类中每个方法都会有一个对应的条目,每个条目保存有一个方法实现代码的地址。
当Main函数第一次调用程序中的某个方法时,JITCompiler函数将被调用,也就是将该方法的IL代码编译成本地的CPU指令,注意这是即时编译的,这些本地CPU指令将被保存在一个动态分配的内存块中,然后JITCompiler将前面内部数据结构中被调用方法的地址替换为包含本地CPU指令的内存块地址。最后JITCompiler将跳转到该内存块的代码上。这就是即时编译所做的工作,当该方法执行完毕,它将返回到Main函数中,继续执行下面的代码。
Main函数第二次调用程序的某个方法时,该方法的IL已经被编译成CPU指令,所以这一次执行将直接调用内存块中已有的本地代码,也正因为如此,一个方法只有在首次调用时才会产生一些性能上的损失。但所有对该方法的后续调用都将以本地代码全速执行。
JIT编译器将本地代码存储于动态内存之中,这就意味着关闭程序时,编译生成的本地代码将会被丢弃。再次运行程序依旧要把IL代码转换为CPU指令,这就是为什么每次运行都需要CLR及.net框架支持的原因。