CLR的执行模型

CLR(通用语言运行时)

JIT(及时编译器)

IL(中间语言)

CLS(公共语言规范)

FCL(Framework class libarly)

CTS(通用类型系统)

托管模块

中间语言IL
  元数据(一个数据表集合,比如类型及成员,导入的类型和成员.....)
    元数据和IL文件关联

程序集

  程序集是一个或多个模块/资源文件的逻辑性分组.
  编译器默认将生成的托管模块转换成程序集.

执行方法

  ->把方法的IL转换成本机CPU指令,这是CLR的JIT编译器的职责
    执行一个方法,首先CLR会检测出代码所引用的所有类型,
      ->分配一个内部数据结构来管理对引用类型的访问
      ->这个类型定义的每个方法都有一个对应的记录项,每个记录项都含有一个地址
      ->在初始化结构时,CLR将每个记录项都设置成包含在CLR内部的一个未编档函数
        JITCompiler(未编档函数)
          ->在负责实现类型的程序集的元数据中查找被调用的方法
          ->从元数据中获取该方法的IL
          ->分配内存块
          ->将IL编译成本机CPU指令,然后放在分配好的内存块中
          ->在Type表(上面的那个内部的数据结构)中修改与方法对应的条目使它指向分配好的内存块
          ->跳转到内存块中的本机代码

  JIT优化

    NGen.exe
      提高应用程序的启动速度
      >因为代码已经编译成本机代码,运行时不需要在花时间编译
        减小应用程序的工作集(指进程的所有内存中,已映射的物理内存那一部分)
    system.Runtime.ProfileOptimization
      该类 导致CLR检查程序运行时哪些方法被JIT编译,结果被记录到一个文件
      原理:
        用其他线程并发编译这些方法

IL和验证

将IL编译成本机CPU指令时,CLR执行一个名为验证的过程,这个过程会检查高级IL代码,确定代码所做的一切都是安全的
  >托管模块的元数据包含验证过程要用到的所有方法及类型信息.
Windows的每个进程都有自己的虚拟地址空间,这样做是为了获得健壮性与稳定性;一个进程干扰不到另一个进程
  >通过验证托管代码,就可以在一个进程中运行多个应用程序了,通过AppDomain

不安全的代码

  将用unsafe包含起来,还需要启用unsafe编译器开关
  当JIT编译器编译一个unsafe方法时,会检查该方法所在的程序集是否被授予了
    >System.Security.Permissions.SecurityPermission权限,而且System.Security.Permissions.SecurityPermissionFlag的SkipVerification
      >标志是否设置.如果设置了该标志,JIT编译器会编译不安全代码,并允许执行
  可以用PEVerify.exe来检查一个程序集的所有方法,并报告其中含有不安全代码的方法

Framework 类库(FCL)
  通用类型系统CTS(Common Type System)
  CLR一切都围绕类型展开.
  CTS规范规定,一个类型可以包含零个或者多个成员
    >字段(Field)
    >方法(Method)
    >属性(Property)
    >事件(Event)
  类型可见性规则以及类型成员的访问规则
    public 任何程序集都能看见并访问该类型
    (assembly)internal 只有在同一程序集可以看见并访问该类型
    private 成员只能由同一个类类型中的其他成员访问
    family(protected) 派生类型可访问,不管是否在同一个程序集
公共语言规范CLS(Common Language Specification)
  定义了所有语言都必须支持的最小功能集
    >可用[assembly:CLSCompliant(true)]这个特性来检查任何公开类型

最后的总结:

  总的来说就是CLR通过CTS将IL代码安全的编译成当前的CPU指令,动态的分配内存空间给CPU指令,然后改变原来方法的地址,然后执行该方法,

    然后返回

 

posted @ 2016-12-14 10:41  夏风微凉  阅读(186)  评论(0编辑  收藏  举报