• CLR执行模型


    好好学习底层运行机制,从CLR via C# 开始。

    CLR的执行模型:

        CLR:Common Language Runtime,是一个可由多种编程语言使用的“运行时”。CLR的核心功能(比如内存管理、程序集加载、安全性、异常处理和线程同步)可由面向CLR的所有语言(C#,Visual Basic,F#等)使用。

    1.将源代码编译成托管模块:                                                  

        CLR根本不关心开发人员用那一种语言来写源代码,说明我我们写C#代码的时候肯定还经过一定的步骤才能跟CLR,于是就需要相应的面向CLR的、可以编译C#代码的编译器,以便CLR可以识别你写的东西。这个编译器会检查语法和分析源代码,产生的是一个托管模块

     

        托管模块是一个可以在CLR中执行的PE(Portal Executable)文件。

        书中介绍托管模块由PE32或PE32+头、CLR头、元数据、IL(中间语言)代码。看的时候个人觉得理解元数据和IL比较重要。

        元数据:包含两种类型的元数据表:一个表描述源代码中定义的类型和成员;另一个表描述源代码引用的类型和成员 。

        IL(中间语言)代码:编译器编译源代码时生成的代码。在运行时,CLR将IL编译成本地CPU指令。(IL代码有时称为托管代码,因为CLR要管理它的执行)

    2. 将托管代码合并成程序集:                                                

    “CLR实际不和模块一起工作。相反,它是和程序集一起工作的。”

        前面说到CLR不会识别你的具体语言,需要相应编译器生成相应的托管模块。这会又说实际不和模块一起工作,引入了程序集的概念。文中说程序集是一个抽象的概念,初学者往往难以把握它的精髓。但我看到程序集(assembly)的时候就有一种无比熟悉的感觉,很经常听到这个词,我感觉我离真相又近了一步。 

        就不再抄书中的概念了,抄个图:

     


    3. 执行程序集的代码:                                                       

        在第一步,即源代码编译成托管模块的时候提到:元数据总是和包含IL代码的文件关联,由于编译器同时生成元数据和代码,把它们绑定一起,并嵌入最终生成的托管模块,所以元数据和它描述的IL代码永远不会失去同步。

        可想而知,当你调用入口方法(Main)的时候,元数据也跟着进来了,它们是一对好基友

     

     

        当你调用Console.WriteLine(“Hello”);时,肯定和它的元数据脱不了干系,元数据可是管着着其定义或者引用的数据结构,所以当Main方法引用了一个Console类型时,就导致了CLR分配一个内部结构。在这个内部结构中,Console类型定义的每个方法都有一个对应的记录项。每个记录项都容纳了一个地址,根据此地址即可找到方法的实现(是不是类似C中的指针?),对这个结构进行初始化时,CLR将每个记录项设置(指向)包含在一个函数中(JITCompiler),图例中可以很清楚的获知JITCompiler 函数的作用。 

        当第二次调用同样的方法时,如Main第二次调用WriteLine。这一次,由于已对WriteLine的代码进行了验证和编译,所以会直接执行内存块中的代码,完全跳过JITCompiler函数。WriteLine方法执行完毕之后,会再次返回Main。所以一个方法只有在首次调用的时候才会造成一些性能损失。以后对该方法的所有调用都以本地代码的形式全速运行,无需重新验证IL并把它编译成本地代码。 

        JIT编译器(JITCompiler)将本地CPU指令存储到动态内存中。一旦应用程序终止,编译好的代码也会被丢弃。

    4. 加载公共语言运行时:                                                     

        你生成的程序集既可以是一个可执行的应用程序,也可以是一个DLL(其中含有一组由可执行程序使用的类型)。最终由CLR管理这些程序集中代码的执行。

        加载公共语言进行时是window的事,我们可以考虑在window的一系列操作之后会初始化CLR,然后加载exe程序集,然后调用其入口方法(Main)。随即,托管的应用程序将启动并运行。

  • 相关阅读:
    截取图片组件
    node之mongodb的DAO
    模块化开发插件,组件
    tweenMax实体抛物线
    defineProperties属性的运用==数据绑定
    程序概述
    JavaBase
    [luogu 1092] 虫食算 (暴力搜索剪枝)
    [luogu1073 Noip2009] 最优贸易 (dp || SPFA+分层图)
    [51Nod 1218] 最长递增子序列 V2 (LIS)
  • 原文地址:https://www.cnblogs.com/likeFlyingFish/p/5346018.html
Copyright © 2020-2023  润新知