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

news2024/12/22 23:57:42

一、什么是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.coloradmin.cn/o/609917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python图像处理优化技巧:提高网站SEO效果的必修课程

Python图像处理优化技巧:提高网站SEO效果的必修课程 介绍 在当前数字化时代,网站的SEO优化已经成为了网站营销的重要一环。在优化网站SEO的同时,提升图像处理技巧也成为了重要的一环。Python作为当前最为火热的数据科学语言之一&#xff0c…

chatgpt赋能python:Python计算圆柱体积的方法

Python计算圆柱体积的方法 Python是一种广泛使用的编程语言,由于其易于学习和使用的特点,许多人在业余时间选择了学习Python。Python可以用来解决各种计算问题,其中包括计算圆柱体积。在本文中,我们将探讨如何使用Python计算圆柱…

chatgpt赋能python:Python在一个程序里调用另一段程序

Python在一个程序里调用另一段程序 随着Python程序的复杂度越来越高,有时候一个程序难以处理所有的任务。这时候我们可能需要将任务拆分成多个脚本来执行。但是,这会导致代码的复杂性增加,同时也会增加可读性和维护成本。这时候,…

LeetCode排序数组(常用排序一一实现)

912. 排序数组 - 力扣(LeetCode) 这道题他会设置一个数据量特别特别大的案例,对于一般的算法是一定过不去的 1.冒泡排序---这种的时间复杂度是O(n*n),对于这道题是不可能过得去的 /*** Note: The returned array must be malloce…

EMQX将数据发送到后端

本文主要是记录了使用免费的EMQX的数据集成功能,将数据流转到后端平台。 在实现过程中,首先是在云服务器之中下载了EMQX,之后通过EMQX的数据集成功能,创建了数据桥接以及与之对应的规则,可以实现将EMQX接收到的数据转发…

C# | 二分查找算法的实现

C# | 二分查找算法的实现 文章目录 C# | 二分查找算法的实现前言示例代码算法思路测试结果结束语 前言 二分查找法一种在有序数组中查找目标值的算法。划重点——“有序”,与需要遍历整个数组的查询算法不同,二分查找法通过将数组分成两部分来快速定位目…

MATLAB-二维图形的绘制

本博文主要介绍绘图函数 Plot 函数的使用,图形的网格、坐标、标题、图例备注以及线型和颜色标记等。 一、Plot 指令 将数据绘制成曲线的函数是 Plot 指令, 该命令可以带有不同数目的参数。最简单的形式就是将数据传递给 Plot , 但是线条的类型和颜色和颜色…

Vue.js 比较重要知识点总结三

概述 Vue 中 nextTick 的实现原理v-if 和 v-show 的区别Vue 中的 key 有什么作用如何理解ref toRef和toRefsComposition API如何实现代码逻辑复用? Vue 中 nextTick 的实现原理 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xf…

chatgpt赋能python:Python在线聊天:实现即时通讯的快速解决方案

Python在线聊天:实现即时通讯的快速解决方案 在当今数字时代,在线聊天已经成为人与人之间交流的主流方式。Python在线聊天应用程序提供了一种快速且可定制的解决方案,使个人用户和企业可以进行互联网通信。本文将向您介绍Python在线聊天的基…

软考A计划-电子商务设计师-电子商务系统建设

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

深挖MYSQL大表加索引

深挖MYSQL大表加索引 起因是这样的,有一张表存在慢sql,查询耗时最多达到12s,定位问题后发现是由于全表扫描导致,需要对字段增加索引,但是表的数据量600多万有些大,网上很多都说对大表增加索引可能会导致锁…

垂直行业(新站)SEO流量快速起飞的核心思路

现在做站不比以前了,不管你是做百度也好,还是谷歌也罢,对于行业精准SEO流量来说肯定是没有以前那么容易做了。但是不容易做不代表没有机会做,机会一直还是有的,尤其是最近百度打击泛站,对于垂直行业来说其实…

chatgpt赋能python:Python图片尺寸大小修改指南

Python图片尺寸大小修改指南 在现代网站设计中,图像是非常重要的一部分。图片质量和大小是网站排名和用户体验的关键因素。一般来说,网站应该尽量避免使用过多的大图片,因为它们会使用户等待过长的时间,同时也会降低网站的加载速…

JAVA基础练习(6)

目录 1.冒泡排列学员成绩(降序) 2.常用Arrays类的应用 2.1.sort 2.2.equals 2.3.toString 2.4.fill 2.5.Arrays.copyOf 2.6.binarySearch 3.利用二维数组计算成绩 1.冒泡排列学员成绩(降序) package ch06;import java.util.Arrays; import java.util…

代码随想录算法训练营第四十一天|343. 整数拆分|96.不同的二叉搜索树

LeetCode343. 整数拆分 动态规划五部曲: 1,确定dp数组(dp table)以及下标的含义:dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。 2,确定递推公式:可以想 dp[i]最大乘积…

下载安装微软office的详细步骤

目录 一、前言 二、下载路径 (一)wps office 办公软件下载地址 1.wps office办公软件下载地址 (二)微软office 办公软件下载地址--2021 1.专业增强版 2.专业版 3.家庭专业版 4.家庭企业版 (三)…

JAVA基础练习(1)

目录 1.练习一:使用变量存储数据,实现个人简历信息的输出 2.练习二:使用Scanner类获取键盘输入的会员卡号,并将该数据存储在变量中,输出这个变量的信息 3.练习三:键盘输入四位数字的会员卡号,使用“/”和“%”运算符分解获得会员卡各个位上…

(二)模拟实现 《资源发现》框架

文章目录 前言资源发现《资源发现》概述技术难点 《资源发现》基本思想《资源发现》框架思考需求分析技术选择 《资源发现》技术难点实现《资源发现》框架实现资源发现基础类实现资源注册中心的实现资源持有者和资源请求者资源持有者和资源请求者功能具体实现 前言 《资源发现…

JAVA基础练习(4)

目录 1.利用循环打印九九乘法表 2.使用循环输出 100、95、90、85.......5 3.输入星期查看对应结果 4.几行数字展示 5.打印1-100之间13的倍数,使用for循环 6.用*来打印,根据用户输入rows和columns,来打印响应矩形 7.输入三个班&#xff…

YOLO8自定义检测实战

文章目录 资料模型介绍(或者叫weights)安装安装ultralytics(yolo)Torch测试命令 CLI命令行通过COCO128数据集体验yolov8标签predictsegment下载COCO 2017数据集ValTrain 自定义数据集标注标注软件labelimg分析训练结果 获得最佳训练结果提示 资料 Docs:…