加载并初始化CLR的过程:
程序集执行
IL代码要通过即时编译器(JIT)转换成本地CPU指令。
方法第一次调用过程?
当程序第一次运行时,会调用JITCompiler函数,它可以知道调用了那些方法,以及定义该方法的类。
然后JITCompiler函数在元数据中搜索该IL代码的位置,验证后转换成本地CPU指令。将指令保存在动态分配的内存中
JITCompiler将被调用方法地址改为第2步的内存地址
跳转到上述代码块上执行代码
执行完成后返回
IL是基于堆栈的语言,而且是无类型的。IL的好处之一是提高程序的健壮性,在将IL代码转换成本地CPU指令时,CLR将执行安全验证的过程,验证失败则会抛出异常。
举个小例子,我们可以看出来有时候能通过编译器的检验,但是运行时还是会抛出异常。
再次调用该方法?
在一个程序中,我们经常反复调用同一个方法,当再次调用该方法时就不需要重复进行验证了,可以直接调用内存块中已有的本地代码,完全跳过JITCompile函数的验证和编译过程。所以同一方法只有在第一次调用时会产生一些性能损失,后续调用就可以全速进行了。
关闭程序?
由于编译器将本地代码保存在动态内存中,所以关闭程序时本地代码将发生丢失。当再次启动程序或者同时运行程序的两个实例时,JIT编译器将再次将IL代码编译为本地指令。