CLR(common language runtime) 公共语言运行时 是一种可由多个编程语言使用的"运行时"
CLR的核心功能(内存管理,程序集加载,安全性,异常处理和线程同步)可由面向CLR的所有语言使用
CLR执行模型
1.将源代码编译成托管模块
在使用对应编译器对一种支持CLR的语言进行编译时,结果都是托管模块(managed model)(包括中间语言(IL)以及元数据(描述模块中定义或引用了什么类型或变量))
2.将托管模块合并成程序集
程序集是一个或多个模块和资源文件的逻辑性分组,具有自描述特性。
3.加载公共语言运行时
以各种配置加载程序集
4.执行程序集代码
为了执行程序集中的托管模块中的方法,必须把IL转换成本机CPU指令,这是JIT(Just In Time)编译器的职责。
如 Console.WriteLine方法执行
首先,先获得方法的类型Console
CLR分配一个内部数据结构,其中记录了Console类型的方法入口,根据入口的地址可以找到方法的实现方式,当这个结构初始化时,CLR将每个记录(方法)的入口地址指向CLR内部的一个函数(JITComplier)
JITComplier函数具体执行
a.在负责实现类型Console的程序集的元数据中查找被调用的方法WriteLine
b.获取该方法IL+验证IL代码
c.分配内存块
d.将IL编译成本机CPU指令,存储在c的内存块中
e.修改那个内部数据结构表中对JITComplier函数的引用转为指向该内存块(含刚才的CPU指令)
注1:在程序第二次执行WriteLine方法时则直接跳过JITComplier函数,直接执行内存块的代码。
注2:
IL验证——为了检查代码安全
核实参数个数,类型,返回值等。
托管模块中的元数据包含的所有方法的类型,信息,可供验证
不安全代码
unsafe
{
int[] array = new int[5];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
fixed (int* p = array)
{
for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(p[i]);
}
}
}
unsafe标志不安全代码段
fixed使得p固定指向array