CLR via C#(一)CLR的执行模型

news/2025/1/11 10:18:59/

一、什么是CLR

CLR全称Common Language Runtime,即公共语言运行时。它可以为所有面向CLR的语言提供运行时的内存管理、程序集加载、安全性、异常处理和线程同步等功能

事实上,CLR并不关心开发者使用的到底是哪种语言,只要这门语言的编译器是面向CLR的,就可以在运行时得到CLR的支持。这是因为这些语言的编译器都会将源代码编译成托管模块

二、什么是托管模块

托管模块是一种标准的Windows可移植执行体文件,需要CLR才能执行。托管模块的组成部分如下图所示:

2.1 IL代码

每个面向CLR的编译器生成的都是IL(中间语言)代码。IL是一种与CPU无关的机器语言,它比大多数CPU机器语言更高级。IL支持访问和操作对象类型,提供了创建和初始化对象的指令,支持调用对象上的虚方法,也支持直接操作数组元素等。所以IL可以看做是一种面向对象的机器语言。在运行时,CLR会将IL编译成本机CPU指令。

2.2 元数据

元数据就是一个数据表的集合。一些数据表描述了模块中定义了什么(类型及其成员),另一些数据表描述了模块引用了什么(导入的类型及其成员)。编译器会同时生成IL代码和描述它的元数据,它们是绑定在一起的,所以永远不会失去同步。

那么元数据有什么用处呢?

  • 可以避免编译时对原生C/C++头和库文件的需求。因为在IL代码中已经包含了有关引用类型/成员的全部信息,编译器可以直接从托管模块中读取元数据。
  • IDE的“智能感知”技术(代码提示、补全)就是通过解析元数据实现的。
  • CLR的代码验证过程使用元数据确保代码只执行类型安全的操作。
  • 元数据允许将对象的字段序列化到内存,将其发送给另一台机器,然后反序列化在远程机器上重建对象的状态。
  • 元数据允许垃圾回收器跟踪对象生命周期(通过元数据知道对象中的哪些字段引用了其他对象)。

三、即时编译(JIT)

前面说了面向CLR的编译器会生成IL代码,这种代码是不能直接执行的,还需要将其转换成本机CPU指令。这就是CLR的JIT(即时)编译器的职责。

来看下面这段代码

public static void Main()
{Console.WriteLine("Hello world");Console.WriteLine("你好 世界");
}

Main()方法执行之前,CLR会检测出Main()方法中的代码引用的所有类型,并分配一个内部的数据结构来管理对引用类型的访问。比如代码中引用了一个Console类型,CLR会分配一个内部数据结构。在这一结构中,Console类型定义的每个方法都会有一个对应的记录。每条记录都包含一个地址,可以通过地址找到方法的实现。在对这个数据结构进行初始化时,CLR将每个记录项都设置成指向包含在CLR内部的一个未编档函数。假设这个函数叫JITCompiler

Main()方法首次调用WriteLine时,JITCompiler就会被调用。而JITCompiler负责将方法里的IL代码即时编译成本机CPU指令。

那么在JITCompiler中具体干了些什么呢?

  • 首先JITCompiler被调用时,它知道要调用的是哪个方法(WriteLine),以及具体是哪个类型定义了该方法(Console)。
  • 然后JITCompiler会在定义该类型的程序集的元数据中查找被调用的方法的IL。
  • 接下来JITCompiler会验证IL代码,并将其编译成本机CPU指令。这些指令会保存到动态分配的内存块中。
  • 然后JITCompiler回到之前的“内部数据结构”,找到调用方法的那条记录,将其指针指向内存块。
  • 最后JITCompiler跳转到内存块,执行完毕其中的指令,并一路返回Main()

接下来,Main()要执行第二条语句,仍然是WriteLine方法。此时“内部数据结构”中的记录已经指向了编译好指令的内存块,所以会直接执行,完全跳过了JITCompiler。也就是说方法仅在首次调用时会有一些性能损失,以后再次调用时都以本机指令的方式全速运行,无需再次编译。 当然,一旦程序终止,编译好的代码块也会丢弃。所以当再次运行时又需要重新编译。

四、参考资料

[1].《CLR via C# 第四版》


http://www.ppmy.cn/news/217213.html

相关文章

队列的实现

队列的基本思想是:先入队列的,先出队列 一、链表实现队列 public class MyLinkedList {class Node{public int val;public Node next;public Node(int val){this.val val;}}public Node head;public Node last;public int usedSize;//入队public void…

Nginx服务性能和安全优化(念念不忘,必没回响)

一、配置Nginx隐藏版本相关信息 1.隐藏版本号 修改 nginx.conf 文件,在http块中添加字段后,重载服务 获取报文信息并查看(浏览器查看或使用命令) 2.修改版本号及相关信息 如果做了上一步在nginx.conf 中添加了 server_tokens…

【MD5】什么是MD5?md5的简要描述

什么是MD5 一、MD5概述二、MD5的主要特点三、MD5的性质四、MD5破解五、MD5防破解六、MD5的用途 一、MD5概述 MD5:英文全称是 Message-Digest Algorithm 5。 中文名为 消息摘要算法第五版。它是消息摘要算法,属于 Hash 算法的一种。 正常情况下&#xf…

入手评测 i58300h和i510210u哪个好

i5-10210U采用14nm工艺,4核心8线程,频率1.6-4.2GHz,6MB三级缓存,采用UHD核显(24 EU),TDP 15W,内存频率由DDR4-2666。选i58300h 还是i510210u 这些点很重要!看完你就知道了http://www…

r7 3750h和i5 8300h 哪个好

AMD Ryzen 7 3750H采用4核8线程的配置,基准频率为2.3GHz,最高加速频率为4.0GHz,配备4MB三级缓存,集成Radeon RX Vega 10 Mobile核芯显卡,TDP为35W。 选r5 3550h还是r7 3750h这些点很重要!看完你就知道了 http://www.ad…

酷睿i5 8300h属于什么级别 i58300h什么水平

i5-8300H采用四核八线程的架构,CPU主频为2.3GHz,最大支持内存为64GB;内存类型包括DDR4 2666MHz,LPDDR3 2133MHz,最大内存通道数为2,最大内存带宽是41.8GB/s,不支持ECC内存。在处理器的特性上&am…

i78750h和i58300h对比哪个好

i5-8300H:4核心8线程,coffcelake架构,主频2.3GHz,单核最大睿频4GHz,四核最大睿频3.9GHz,L3缓存8MB,TDP45W,核显UHD630,理论性能接近桌面级处理器i7-7700。 i78750h和i583…

ubuntu中的坑——ubuntu18.04版本下安装NVIDIA显卡驱动

我的电脑参数: 电脑型号:msi gv62 8rd CPU:intel corei5 8300h 独立显卡GPU:gtx1050ti 内存:8g 方法来自CSDN论坛:https://blog.csdn.net/wf19930209/article/details/81877822 综合网上其他的方法&a…