CLR的执行模型

将源代码编译成托管模块


公共语言运行时CLR

  公共语言运行时(Common Language Runtime,CLR)是一个可由多种编程语言使用的“运行时”。它负责在执行时管理代码,提供内存管理、异常处理、线程管理等核心服务,同时又确保代码的安全性和准确性。

源码的编译过程

  源码的编译过程如图所示,使用支持CLR的语言创建源代码文件,然后通过相应的编译器对源码进行语法检查和分析,生成托管模块。托管模块主要由4部分组成:PE32或PE32+头、CLR头、元数据、IL代码。

托管模块的组成部分及说明:

组成部分 说明
PE32或PE32+头 标准的Windows PE文件头,标识出了文件使用何种格式、文件类型、生成时间等信息
CLR头 包含使用这个模块成为托管模块的信息
元数据 主要有两种表:描述源代码中定义的类型和成员;描述源代码引用的类型和成员
IL代码 编译器编译源代码时生成的代码

##将托管模块合并成程序集

  CLR实际不和托管模块工作,它和程序集工作。程序集是一个或多个模块/资源文件的逻辑性分组。程序集是重用、安全性以及版本控制的最小单元。下图展示了一些托管模块和资源文件交由一个工具处理,生成代表文件逻辑分组的一个PE32(+)文件的过程。


##加载公共语言运行时

  Windows检查可执行文件的文件头,决定创建32位还是64位进程,在进程地址空间加载对应版本的MSCorEE.dll文件,调用MSCorEE.dll中的方法初始化CLR,加载程序集,随后调用其入口方法,启动并运行托管应用程序。


##执行程序集的代码

  为了执行程序集的代码,首先要把方法的IL转换为本机CPU指令。这是CLR的JIT(just-in-time)编译器的职责。下图展示了方法调用的执行过程。

执行步骤:

  1. 在Main方法执行之前,CLR会检测出Main的代码引用的所有类型。使CLR分配一个内部数据结构来管理对引用类型的访问(II),在这个数据结构中,Console类定义的每个方法都有一条对应的记录,每条记录都含有一个地址,根据此地址即可找到方法的实现。对这个结构初始化时,CLR将每个记录项都设置成包含在CLR内部的一个未编档函数,我们称之为JITCompiler。
  2. Main方法首次调用WriteLine时,JITCompiler函数被调用,执行III中的操作。
  3. 代码执行完毕后,回到Main中,继续执行下一条语句。
  4. 由于步骤2中已经对WriteLine的代码进行了验证和编译,所以会直接执行内存块中的代码,完全跳过JITCompiler函数。

由以上步骤可知:

  1. 方法仅在第一次被调用时才有一些性能损失。以后的调用都以本机代码的形式全速运行。
  2. JIT编译将本机CPU指令保存在动态内存中。也就是说,一旦应用程序关闭,编译好的代码也会丢失。

##本机代码生成器:NGen.exe

  使用.NET Framework提供的NGen.exe工具,可以在应用程序安装时,将IL代码编译成本机代码。

优点:

  1. 提高应用程序的启动速度。因为已经编译成本地代码,运行时不再需要花费时间编译IL代码
  2. 减小应用程序的工作集。NGen.exe将IL编译成本机代码,并将这些代码保存到单独的文件夹中,该文件通过“内存映射”的方式,同时映射到多个进程地址空间中,使代码得到共享,避免每个进程都需要一份单独的代码拷贝

缺点:

  1. 没有知识产权保护
  2. NGen生成的文件可能失去同步
  3. 较差的执行时性能

##Framework类库

  .NET Framework包含Framework类库(Framework Class Library,FCL)。FCL是一组程序集的统称。以下是常用的FCL命名空间:

命名空间 内容说明
System 包含每个应用程序都要用到的所有基本类型
System.Data 包含用于和数据库通信以及数据处理的类型
System.IO 包含用于执行流I/O以及浏览目录/文件的类型
System.Net 包含进行低级网络通信,并与一些常用Internet协议协作的类型
System.Runtime.InteropService 包含允许托管代码访问非托管操作系统平台功能
System.Security 包含用于保护数据和资源的类型
System.Text 包含处理各种编码文本的类型
System.Threading 包含用于异步操作和同步资源访问的类型
System.Xml 包含用于处理XML架构和数据的类型

##通用类型系统

  CLR一切围绕类型展开。通用类型系统(Common Type System,CTS)是Microsoft制定的一套用来描述类型的定义和行为的规范。

通用类型系统的功能:

  • 建立用于跨语言执行的框架
  • 提供面向对象的模型,支持.NET平台上实现各种语言
  • 定义处理类型时所有语言都必须遵守的一组规则
  • 提供包含应用程序开发中使用的基本基元数据类型的库

CTS规范规定,一个类型可以包含零个或多个成员(字段,方法,属性,事件)。另外,CTS还指定了类型的可见性规则以及类型成员的访问规则。除此之外,CTS还为类型基础、虚方法、对象生存期等定义了响应的规则。


##公共语言规范

  要创建从其他编程语言中访问的类型,只能从自己的语言中挑选其他语言都支持的功能。Microsoft定义了公共语言规范(Common Language Specification,CLS),它详细定义了最小的功能集。
CLS定义的是CLR/CTS功能的一个子集。



与非托管代码的互操作性


CLR支持三种互操作情形:

  • 托管代码能调用DLL中的非托管函数
  • 托管代码可以使用现有COM组件
  • 非托管代码可以使用托管类型
posted @ 2017-08-05 14:41  Answer.Geng  阅读(697)  评论(0编辑  收藏  举报