Ecma335、CLR、CLI、CTS、 IL、.net 以及他们之间的关系
以上是个人对他们直接关系的理解:图片是原创
CLI 通用语言基础架构(Common Language Infrastructure), CLI是一个开放型的技术规范,它定义了一个语言无关的跨体系结构的运行环境,这使得开发者可以用规范内定义的各种高级语言来开发软件,并且无需修正即可将软件运行在不同的计算机体系结构上.由微软、惠普和英特尔于2000年向ECMA倡议的。最终定义为Ecma335标准。
该标准化文件包括以下六个部分:
- 通用类型系统(Common Type System, CTS)
- 通用语言规范(Common Language Specification, CLS)
- 元数据系统(Metadata)
- 虚拟执行系统(Virtual Execution System, VES) 个人理解 这个就是CLR
- 通用中间语言(Common Intermediate Language, CIL)
- 框架(Framework) 个人理解 这个就是FCL BCL等类库
以上来自Wiki:https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E8%AF%AD%E8%A8%80%E6%9E%B6%E6%9E%84
CLR: 托管代码执行引擎,CLR主要提供了一下功能:
- 即使编译 (JIT)
- 内存管理 (Memory Management)
- 线程管理 (Thread Management):每一次程序至少有一个CLR实例,每个CLR负责一个线程池,clr的线程等价于windows线程
- 垃圾回收 (Garbage Collection)
- 安全性 (Security)
- 类型检查 (Type Checker)
- 异常处理 (Exception Manager)
- 基类库支持 (Base Class Library Support)
- 反射服务
CTS, Common Type System, 通用类型系统。
需要记住的是CLR所有功能的实现都是基于类型的。一个类型将功能提供给一个应用程序或者另一个类型来使用。通过类型,用一种编程语言写的代码能与用另一种语言写的代码沟通。由于类型是CLR的根本,微软专门为如何定义、使用和管理类型定义了一个正式的规范-- 通用类型系统(Common Type System),即CTS。
CTS对类型的定义和行为特性给出了规范,这些特性包括但不仅限于以下几点:
- 类成员(Field、Method、Property、Event)
- 访问可见性级别(private、family、family and assembly 、assembly、family or assembly 、public)
- 类型的继承
- 接口
- 虚方法
- 对象的生命周期
同时,所有引用类型都必须继承自System.Object的规则也是在CTS中定义的。
CLS:Common Language Specification, 通用语言规范
一般来说,CLS主要提供了一下功能:
- 建立一个支持跨语言集成、类型安全和高性能代码执行的框架环境。
- 提供一个支持完整实现多种编程语言的面向对象的模型。
- 定义各语言必须遵守的规则,有助于确保用不同语言编写的对象能够交互作用。
- 提供包含应用程序开发中使用的基元数据类型(如Boolean、Byte、Char、Int32 和 UInt64)的库。
CLR是如何工作的
借用维基百科上的一副图来描述CLR的运行流程:
从源代码到应用程序执行CLR主要做了以下工作:
将源代码编译成托管模块
托管模块是一个标准的 32 位 Microsoft Windows 可移植执行体(PE32)文件,或者是一个标准的 64 位 Windows 可移植执行体(PE32+)文件,它们都需要 CLR 才能执行。一个托管模块主要包含一下几部分信息:
PE32货PE32+头
这里描述了当前托管模块的基本信息,包括运行的Windows版本、文件类型、生成时间等。对于包含本地 CPU代码的模块,这个头包含了与本地 CPU 代码有关的信息。
CLR头
包含使这个模块成为一个托管模块的信息(可由 CLR 和一些实用程序 进行解释)。头中包含了需要的 CLR 版本,一些 flag,托管模块入口方 法(Main 方法)的 MethodDef 元数据 token,以及模块的元数据、资 源、强名称、一些 flag 以及其他不太重要的数据项的位置/大小
元数据
每个托管模块都包含元数据表。主要有两种类型的表:一种类型的表 描述源代码中定义的类型和成员,另一种类型的表描述源代码引用的 类型和成员
IL (中间语言)代码
编译器编译源代码时生成的代码。在运行时, CLR 将 IL 编译成本地 CPU 指令
将托管模块合并成程序集
CLR 实际不和模块一起工作,而是和程序集一起工作的。可以从以下两点对程序集有一个初步的认识:
- 首先,程序集是一个或多个模块/资源文件的逻辑性分组。
- 其次,程序集是重用、安全性以及版本控制的最小单元。
加载CLR
在这一步,Windows 检查好 EXE 文件头,决定是创建 32 位、 64 位还是 WoW64 进程之后,会在进程的地址空间中 加载 MSCorEE.dll 的 x86,x64 或 IA64 版本。如果是 Windows 的 x86 版本,MSCorEE.dll 的 x86 版本在 C:\Windows\System32 目录中。如果是 Windows 的 x64 或 IA64 版本,MSCorEE.dll 的 x86 版本在 C:\Windows\SysWow64 目录中,64 位版本(x64 或者 IA64)则在 C:\Windows\System32 目录中(为了向后 兼容)。然后,进程的主线程调用 MSCorEE.dll 中定义的一个方法。这个方法初始化 CLR,加载 EXE 程序集, 然后调用其入口方法(Main)。随即,托管的应用程序将启动并运行。
执行程序集中的代码
到目前为止,源代码已经被编译成二进制的IL并且包含在程序集中,而且被CLR加载。但是,直接执行运算的CPU来说二进制的IL还是太高级了,而且不同的CPU支持的指令集也有所差异。因此,CLR在这里还需要对已经编译好的IL再次编译,针对CPU版本生成可以直接运行的CPU指令,这个过程是由JIT(Just In Time)编译器完成的,可以称作“即时编译”。
当第一次执行某个函数时,MSCorEE.dll 的JITCompiler函数会从程序集的元数据中获取该方法和方法的IL,并且分配一块内存地址,然后将IL编译成的本地代码放入这块内存,然后执行内存中的本地代码。
当再次执行这个函数的时候,由于内存中已经存在JIT编译好的本地代码,因此不需要再次进行JIT过程,可以直接执行内存中的本地代码。 可以预知的结果是,这种情况下应用程序启动后第一次调用某个模块所花费的时间要比以后调用这个模块要稍微多一些。
现在,通过本地代码生成技术,已经可以在编译阶段就根据计算机的的实际环境生成本地代码,这样以来就可以在运行时节省JIT编译的时间,提高程序的启动效率。这看起来是一个不错的功能,但是实际上运用的不是很广泛,主要是有一下限制:
- 编译时生成的本地代码太过于依赖本地环境,一旦环境有变化 (包括操作系统更新、.Net Framework版本更新、CPU更换等),以前生成的本地代码都不再适用。
- 编译时生成的本地代码必须要和程序集保持同步。
- 编译时生成的本地代码不能像运行时JIT编译那样根据运行时的情况对代码进行优化。
CL有哪些功能
这里借用Jeffrey Richter的一段原话:
At first, I thought that the .NET Framework was an abstraction layer over the Win32 API and COM. As I invested more and more of my time
into
it, however, I realized that it was much bigger. In a way, it
is
its own operating system. It has its own memory manager, its own security system, its own file loader, its own error handling mechanism, its own application isolation boundaries (AppDomains), its own threading models, and more.
虽然原文中Jeffrey Richter说的是.Net Framework,但很显然这些功能都是.Net Framework的核心组件CLR来提供的,正是CLR使.Net Framework并不是Win32 API和COM的一个抽象层,而是有了自己的"操作系统"(Jeffrey Richter的意思应该是在一定程度上,虚拟机也可以认为是一个小型的操作系统)。总结起来,CLR主要提供了一下功能:
- 基类库支持 (Base Class Library Support)
- 内存管理 (Memory Management)
- 线程管理 (Thread Management)
- 垃圾回收 (Garbage Collection)
- 检查内存安全和类型安全;
- 程序集加载
- 异常处理 (Exception Manager)
- 即使编译 (JIT)
本系列主要围绕以上功能对CLR进行探讨。
IL,Intermediage Language,中间语言,CLR把C# java F#等语言编写的代码都统编译成IL,这样就可以在IL 这一层实现 所有编程语言的统一。vs将编译后的IL存储在程序集中(Dll\exe)l文件中。 当打开软件的时候 CLR程序集中的IL 二次编译成机器可识别的语言。
由于不同语言所写的程序集在IL层面已经实行统一,所以c# 可以调用F#的程序集,java也可以调用C# 写的程序集。
.net: 是一个程序开发、运行平台,它是CLI的实现,它是要实现让程序源跨语言开发软件、让开发出来的软件跨平台 、跨系统运行。
引用来源:https://www.cnblogs.com/Gamain/p/3452891.html
Ecma335、CLR、CLI、CTS、 IL、.net 以及他们之间的关系的更多相关文章
- C# 中间语言、CLR、CTS、CLS
c# 中间语言.CLR.CTS.CLS IL中间语言,区分大小写 中间语言的主要特征: 1. 面向 对象和使 用接口 2. 值类型和引 用类 型之间的 显 著差异 3. 强 数据类型化 4. 使 ...
- .Net框架中的CLR,CTS,ClS的解释
CLR的全称(Common Language Runtime) 公共语言运行时 可以把它理解为包含运行.Net程序的引擎 和 一堆符合公用语言基础(CLI)的类库的集合,他是一个规范的实现,我们开发的 ...
- CLR/.NET/C#/Visual Studio/ASP.NET各版本之间的关系(转)
由于这篇文章记录的是2015年7月,那时.net core还是叫做.net core 5 名词定义 下列这些名词,写.NET 的人一定都不陌生,但你是否有真正理解呢?如果看了我的摘要文字说明还无法理解 ...
- C++/CLI 本地字符串和托管字符串之间的转换
参考: https://docs.microsoft.com/zh-cn/cpp/dotnet/overview-of-marshaling-in-cpp #include "msclr/m ...
- 亚马逊s3存储: aws cli上传工具速度和各文件大小关系探究
1,背景介绍 公司最近最近统一了存储环境,由ftp文件存储全量转换为ceph存储.有业务组表示以前往ftp文件批量上传30万个文件1.3GB只需要16分钟左右.切换为ceph存储需要1个多小时,也就是 ...
- .NET学习笔记 -- 那堆名词到底是啥(CLR、CLI、CTS、CLS、IL、JIT)
什么是CLR? CLR,公共语言运行时(Common Language Runtime)是一个由多种语言使用的“运行时”.他的核心功能包括(内存管理.程序集加载.安全性.异常处理和线程同步),可以被面 ...
- (转)什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?
转自:http://www.cnblogs.com/haofaner/articles/2288968.html 1:什么是.NET? NET 是 Microsoft 的用以创建 XML Web 服务 ...
- 什么是.NET CLI CLR IL JIT GC,它们是如何工作的
参考网址: https://cloud.tencent.com/developer/article/1432891 1:什么是.NET? NET 是 Microsoft 的用以创建 XML Web 服 ...
- 浅谈CLR CTS CLS。。。
So The First Is CLR CLR的全程是Common Language Runtime 公共语言运行时 可以把他理解为包含运行.net程序的引擎 和 一堆符合公共语言基础(CLI)的类 ...
随机推荐
- Cesium和Kaarta用高分辨率激光雷达可视化室内和地下环境
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Cesium使急救人员和军事操作人员更容易快速评估和了解密集和不 ...
- [源码分析] Facebook如何训练超大模型 --- (3)
[源码分析] Facebook如何训练超大模型 --- (3) 目录 [源码分析] Facebook如何训练超大模型 --- (3) 0x00 摘要 0x01 ZeRO-Offload 1.1 设计原 ...
- sort排序出现安卓与苹果系统排序不一致问题
sort排序出现安卓与苹果系统排序不一致问题
- [源码分析] Facebook如何训练超大模型---(4)
[源码分析] Facebook如何训练超大模型 --- (4) 目录 [源码分析] Facebook如何训练超大模型 --- (4) 0x00 摘要 0x01 背景知识 1.1 单精度.双精度和半精度 ...
- Redis 源码简洁剖析 04 - Sorted Set 有序集合
Sorted Set 是什么 Sorted Set 命令及实现方法 Sorted Set 数据结构 跳表(skiplist) 跳表节点的结构定义 跳表的定义 跳表节点查询 层数设置 跳表插入节点 zs ...
- 学习Java第6天
今天所做的工作: 1.完成学生信息管理系统样卷 2.核心技术接口继承,多态 明天工作安排: 1.类的高级特性(Java类包) 2.异常处理 今天做一个小小的总结,Java程序是完全面向对象的,它的所有 ...
- python操作MySQL数据库连接
目录 一:python操作MySQL 1.python如何操作MySQL? 2.什么是 PyMySQL? 二:PyMySQL 安装 1.方法一: 2.方法二: 三:pyMySQL模块基本使用 1.py ...
- Android 如何让EditText不自动获取焦点&隐藏软键盘
感谢大佬:https://blog.csdn.net/a18615971648/article/details/72869345 有时候的项目当中进入某个页面edittext会自动获取焦点弹出软键盘, ...
- copy与内存管理
1.copy与内存管理 浅拷贝 原对象引用计数器+1 必须对原对象进行释放 char *cstr = "this is a c string"; NSString *str1 = ...
- docker平时使用异常记录
GPU主机重启后,启动使用GPU的容器报错 docker: Error response from daemon: Unknown runtime specified nvidia. 解决办法:修改/ ...