【前言】

  • 方法执行前,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. DAY13-前端之BOM和DOM

    前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...

  2. eclipse中创建maven web项目

    本文主要说明将maven web项目转成eclipse支持的web项目. 创建一个maven项目设置打包类型为war则其为web项目 结构如下 将mavenweb项目转成eclipse识别的web项目 ...

  3. MSSQL 数据库日志爆涨

    解决方法有两种,现只用最简单的方法: 1.数据库属性----选项----恢复模式由完整改为简单--确定 2.右击数据库---任务---收缩 3.数据库属性----选项----恢复模式由简单改为完整-- ...

  4. Ros学习——值得学习的package

    RViz是一款强大的可视化工具,它允许你查看机器人中的传感器和内部状态. TF程序包(package)提供在机器人所使用到的各种坐标系之间的变换功能,并保持跟踪这些变换的变化. actionlib - ...

  5. 一个典型的PHP分页实例代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. ReentrantLock的简单使用

    ReentrantLock: /** * ReentrantLock测试逻辑类 */ public class MyService { private Lock lock = new Reentran ...

  7. redis 有用

     浅谈redis   (1)什么是redis? Redis 是一个基于内存的高性能key-value数据库. (有空再补充,有理解错误或不足欢迎指正)   (2)Reids的特点 redis本质上是一 ...

  8. DPDK内存管理(1)(转)

    1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal            是统一 ...

  9. Fiddler的Request Builder(Composer)模拟发送POST请求

    传json格式: Parsed写: User-Agent: Fiddler Host: localhost:1455 Content-Type: application/json; charset=u ...

  10. VS2012,更新补丁后--创建项目未找到与约束匹配的导出

    更新过一次漏洞,后来尝试建立一个项目,结果错误终于暴露了,创建项目时无法成功创建,而且提示:未找到与约束ontractNameMicrosoft.VisualStudio.Text.ITextDocu ...