第一部分 CLR基础:第1章 CLR的执行模型
1.1将源代码编译成托管模块
每个面向CLR的编译器生成的都是IL(中间语言)代码,或称为托管代码,因为CLR管理它执行;另外编译器还要在每个托管模块中生成完整的元数据,元数据是一组数据表,一些数据表描述模块中定义的内容,比如类型及其成员。还有一些元数据表描述了托管模块引用的内容,比如导入的类型及其成员。
元数据作用:1.编译后可以解析元数据,才有“智能感知”。2.将对象属性序列化和反序列化。
注:CLR(Common Language Runtime)公共语言运行时 核心功能:内存管理、程序集加载、安全性、异常处理、线程同步
1.2将托管模块合并成程序集
清单是有一个或多个元数据表构成的集合,描述构成程序集的文件。
程序集是一个或多个模块/资源文件的逻辑分组。“程序集”可以将一组文件当作一个实体来对待。
1.3加载公共语言运行时
生成的程序集可以是exe文件或dll文件,最终由CLR管理执行。
1.4执行程序集的代码
可以将IL看作是一种面向对象的机器语言。
执行一个方法:IL -> CPU指令(由CLR的JIT just-in-time即使编译器的来转换)
Main方法执行前,CLR检测出Main代码引用的所有类型,分配一个内部数据结构来管理对所引用类型的访问。上图中内部结构中,Console类型定义的每个方法都有一个对应的记录项,每个记录都容纳了一个地址,根据地址可以找到方法的实现。
对这个结构进行初始化时,CLR将每个记录项都设置成(指向)包含在CLR内部的一个未文档化的函数(JITCompiler)。
Main方法首次调用WriteLine时,JITCompiler函数会被调用。JITCompiler函数负责将一个方法的IL代码编译成本地CPU指令。
JITCompiler
函数被调用时,它知道要调用的是哪个方法,以及具体是什么类型定义了该方法。然后,JITCompiler会在定义(该类型的)程序集的元数据中查找被调
用的方法的IL。接着,JITCompiler验证IL代码,并将IL代码编译成本地CPU指令。本地CPU指令被保存到一个动态分配的内存块中。然
后,JITCompiler返回CLR为类型创建的内部数据结构,找到与被调用的方法对应的那一条记录,修改最初对JITCompiler的引用,让它指
向内存块中的代码。这些代码正是WriteLine方法(获取String参数的那个)的具体实现。这些代码执行完毕并返回时,会返回到Main中的代
码,并像往常一样继续执行。
个人简化理解:CLR 检查方法中引用的类型,分配一个内部数据结构来保存对类型的访问,类型中定义的方法对应一个记录,记录指向CLR内部函数JITCompiler,方法调 用后对应的JITCompiler开始执行,找到程序集元数据中方法的IL,验证IL,转换为CPU指令并保存到动态内存中,将记录修改指向这个内存中的 代码,执行代码,返回,程序继续往下执行...
1.6 Framework类库
.NET Framework中包含了Framework类库(Framework Class Library,FCL),FCL是一组DLL程序集的统称。
1.7通用类型系统
微软制定的正式类型规范:Common Type System,CTS 它描述了类型的定义和行为。
方法签名:是否有返回值,返回值的类型;参数的类型、数量及顺序。
1.8公共语言规范
公共语言规范(Common Language Specification, CLS),任何编译器生成的类型想兼容于其他“符合CLS、面向CLR的语言”所生成的组件,就必须支持这个最小功能集。允许一种语言中使用由另一种语言创建的对象。