【前言】

  • 方法执行前,CLR 会检测方法内代码引用的所有类型。同时 CLR 会分配一个内部数据结构,用来管理对所有引用的类型的访问。
  • 首次执行方法时,托管程序集会把 IL 转换成本地 CPU 指令,并将其存储在一个动态分配的内存块中。 这是 CLR 的 JIT(just-in-time)编译器的功能。
  • 在应用程序终止前,如果再调用同一个方法,会直接执行存储在动态分配内存块里的 CPU 指令。

【图解】

1.当 “首次” 执行方法时,实际发生的事情如下图所示

就在 Main 方法执行之前,CLR 会检测出 Main 的代码引用的所有类型。这导致 CLR 分配一个内部数据结构,它用于管理对所有引用的类型的访问。如上图所示,Main 方法引用了一个 Console 类型,这导致 CLR 分配一个内部结构。在这个内部数据结构中,Console 类型定义的每个方法都有一个对应的记录项。每个记录项都容纳了一个地址,根据此地址即可找到方法的实现。对这个结构进行初始化时,CLR 将每个记录项都设置成(指向)包含在 CLR 内部的一个未文档化的函数。我们将这个函数称为 JITCompiler。

Main 方法首次调用 WriteLine 时,JITCompiler 函数会被调用。JITCompiler 函数负责将一个方法的 IL 代码编译成本地 CPU 指令。由于 IL 是“即时”(just in time)编译的,所以通常将 CLR 的这个组件称为 JITer 或者 JIT 编译器。

JITCompiler 函数被调用时,它知道要调用的是哪个方法,以及具体是什么类型定义了该方法。然后,JITCompiler 会在定义(该类型的)程序集的元数据中查找被调用的方法的 IL。接着,JITCompiler 验证 IL 代码,并将 IL 代码编译成本地 CPU 指令。本地 CPU 指令被保存到一个动态分配的内存块中。然后, JITCompiler 返回 CLR 为类型创建的内部数据结构,找到与被调用那个的方法对应的那一条记录,修改最初对 JITCompiler 的引用,让它现在指向内存块(其中包含了刚才编译好的本地 CPU 指令)的地址。最后,JITCompiler 的函数跳转到内存块中的代码。这些代码正是 WriteLine 方法(获取单个 String 参数的那个版本)的具体实现。这些代码执行完毕并返回时,会返回到 Main 中的代码,并像往常一样继续执行。

2.方法 “再次” 执行时,实际发生的事情如下图所示

第二次调用 WriteLine。这次由于已对 WriteLine 的代码进行了验证和编译,所以会直接执行内存块中的代码,完全跳过 JITCompiler 函数。 WriteLine 方法执行完毕之后,会再次返回 Main。

注意:JIT 编译器将本地 CPU 指令存储到动态内存中。一旦应用程序终止,编译好的代码也会被丢弃。所以,如果将来再次运行应用程序,或者同时启动应用程序的两个实例(使用两个不同的操作系统进程),JIT 编译器必须再次将 IL 编译成本地指令。

读经典——《CLR via C#》(Jeffrey Richter著) 笔记_方法执行的更多相关文章

  1. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_发布者策略控制

    在 读经典——<CLR via C#>(Jeffrey Richter著) 笔记_高级管理控制(配置)中,是由程序集的发布者将程序集的一个新版本发送给管理员,后者安装程序集,并手动编辑应用 ...

  2. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据

    [实例代码] using System; public sealed class SomeType //-------------1 { //嵌套类 private class SomeNestedT ...

  3. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(二)

    [基元类型推荐] 推荐直接使用 FCL 类型. [理由] 编码时不至于困惑string与String的使用.由于C#的stirng(一个关键字)直接映射到System.String(一个 FCL 类型 ...

  4. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(一)

    [概念] 编译器直接支持的数据类型 [C#基元类型与对应的 FCL 类型] C#基元类型 FCL 类型 说明 sbyte System.Sbyte 有符号8位值 byte System.Byte 无符 ...

  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_高级管理控制(配置)

    一个应用程序的XML配置文件示例: <?xml version="1.0"?> <configuration> <runtime> <as ...

  6. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_运行时解析类型引用

    public sealed class Program{ public static void Main() { System.Console.WriteLine("Hi"); } ...

  7. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_元数据

    1.元数据简介 全称:metadata 属性:数据表集合 产地:面向 CLR 的编译器在托管模块中生成 2.元数据内部结构及与托管模块的关系 [概述] 托管模块中包含着元数据,元数据是由一组数据表组成 ...

  8. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_友元程序集

    [应用场景] 程序集A访问程序集B定义的Internal访问类型的类的成员. [使用方式] 在构建程序集B的时候,引入System.Runtime.CompilerServices,以此来添加Inte ...

  9. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_类型的各种成员

    [Class中,可能包含的成员] 常量, 字段, 实例构造器, 类型构造器, 方法, 操作符重载, 转换操作符, 属性, 事件, 类型(Class)

随机推荐

  1. windows下查看端口占用(砖)

    第一步,执行命令:netstat -ano -a 显示所有连接和监听端口 -n 以数字形式显示地址和端口号. 此选项一般与 -a选项组合使用 -o 显示与每个连接相关的所属进程 ID. Active ...

  2. Ajax入门(二)Ajax函数封装

    如果看了的我上一篇博客<Ajax入门(一)从0开始到一次成功的GET请求>的话,肯定知道我们已经完成了一个简单的get请求函数了.如下: 1234567891011121314151617 ...

  3. 【总结整理】IFeatureBuffer

    IFeatureBuffer pRowBuffer = objTabWYDCQ_Tar.CreateFeatureBuffer(); pRowBuffer.Shape = SourceRow.Shap ...

  4. POJ 3714 分治/求平面最近点对

    第一次见这种问题直接懵圈...没想到分治法这么强大,借鉴了lyd的代码: 代码如下 #include<cstdio> #include<algorithm> #include& ...

  5. 怎么把网页保存为pdf文件

    不就是用chrome浏览器打印功能,然后保存为pdf就可以了吗? 对于一些结构简单的比如,RFC文档这样操作一般没什么问题,对于一些有浮动元素的网页就不好说了,必须先用chrome的审查元素把一些不必 ...

  6. 3D模型浏览器的实现思路

    前段时间正好浏览了数据结构中关于图的部分,突然就意识到一个问题,3D模型就是用无向图来存储的.仔细想一想是不是这样呢? 一个3D模型去掉材质之后剩下的部分就是点以及点和点之间的连线了,点我们用三维坐标 ...

  7. Damn Couples ZOJ - 3161

    传送门 题目大意 N个人,M组关系,每次选一种关系,如果两个人相邻,则任意删除其中一个,否则不变.问最坏情况下最多能剩多少人. 分析 为了留的人最多,我们可以先将原来不相邻的关系全部说完,这样我们只需 ...

  8. hadoop运行常见问题FAQ

    问题1:Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-outAnswer:程序里面需要打开多个文件,进行分析,系统一般默认数量是 ...

  9. post请求时,出现relationship name error

    原因:在post请求,其属性名在代码中已经修改为partyLocationDtos,但是在swagger中,仍然为partyLocations. 因此,报错.记住,在post请求的时候,要一一对应.写 ...

  10. java全栈day07---Eclipse开发工具 超市库存管理系统

    前六天我们都是用Notepad++来编写java程序,通过DOS命令来运行,我们发现这样比较繁琐,那么我们今天就用一个工具Eclipse来开发java Eclipse的下载安装 * A: Eclips ...