什么是CLR?

CLR,公共语言运行时(Common Language Runtime)是一个由多种语言使用的“运行时”。他的核心功能包括(内存管理、程序集加载、安全性、异常处理和线程同步),可以被面向CLR的所有语言使用。这里的“运行时”,就是一个运行时环境,就像JAVA虚拟机一样。哦,错了,确切的说是JRE(Java  Runtime Enviromental)。JVM确切的说不是一个实体的java虚拟机,而是一个规范,就像CLI一样。会有不同的实现,如:JRockit还是Hotspot(前者是Oracle的JVM商业实现,后者是Sun的开源实现——当然现在也是Oracle的)

什么是CLI?

公共语言基础结构(Common Language Infrastructure),定义了构成.NET Framework基础结构的可执行代码,以及代码运行时的环境规范。它定义了一个与语言无关的跨体系结构的运行环境,这使得开发者可以用规范内定义的各种高级语言来开发软件,并且无须修正即可将软件运行在不同的计算机体系结构上。CLI是一个开放型的技术规范,由微软、惠普和英特尔于2000年向ECMA倡议的。说白了,CLI就是一套规范,CLR是对CLI的一种实现。那么CLI这份规范中具体定义了哪些内容呢?不妨去ECMA的网站下一份看看,也可以在这里下载:

如上面截图所示:包含了6部分,:

Partition I: Concepts and Architecture –描述.NET CLI的全部体系结构,提供公共类型系统(CTS,Common Type System)、虚拟执行系统(VES,Virtual Execution System)和公共语言规范(CLS,Common Language Specification)的标准化描述,还提供对元数据(Metadata)的信息性描述。

通用类型系统(CTS):规范.NET中数据的类型。

元数据系统(Metadata):是.NET中描述数据的数据。

通用语言规范(CLS):描述多语言之间进行交互的语言规范,.NET系统包括的语言有C#、C++、VB、J#,它们都遵守通用语言规范。

虚拟执行系统(VES):是一个可运行受管理代码(Managed Code)的运行环境,它提供了运行受管理代码所需要的内置数据类型(data type),以及假定的机器型态与状态设置、流程控制与例外处理等参数。

Partition II: Metadata Definition and Semantics - 提供元数据的标准化描述,包括元数据在.NET扩展PE文件格式中的位置(以.NET扩展PE文件格式的形式表示),元数据的逻辑内容(以表格及其关联的集合的形式表示,实际上使用了形式化方法表示)和元数据的语义(以汇编成为虚拟机代码的汇编器ilasm理解的形式表示)。

Partition III: CIL Instruction Set描述CIL的指令集(注意,是CIL,不是CLI哦)

Partition IV: Profiles and Libraries- 提供CLI库的简要介绍,以及将其分解为Profile和库的规范。这里有一个配套的文件CLILibraryTypes.xml,考虑过随这一部分一起发布,不过该文件是XML格式的,该文件提供了CLI库中每一个类、值类型和接口的细节说明。“Profile”一词在这里的含义是库的集合,一起组合起来构成提供一定功能级别的一致性整体,换而言之,不同的Profile对应不同的库集合,提供的功能级别也不同。

Partition V: Debug Interchange Format- 描述了CLI 产品的调试交互的标志方式;

Partition VI: Annexes- 提供了一些用ILAsm(CIL Assembly Language)写的例程等

什么是CTS?

CLR是完全围绕类型展开的,通过类型,通过一种编程语言写的代码可以与另一种语言写的代码沟通。所以Microsoft制定了一个正式的规范,“通用类型系统”(Common Type System,CTS),它描述了类型的定义和行为。上面已经提到,Microsoft已经将CTS和,NET Framework的其他组件 -- 包括(文件格式、元数字、中间语言及对底层平台的)提交给ECMA完成标准化工作,最终形成的标准称为“公共语言基础结构”(Common Language Infrastructure)。

CTS里定义了以下内容:

什么是CLS?

CLR中集成了多种语言,一种语言中可以调用另一种语言创建的对象。为了实现这一目的,微软定义了一个公共语言规范(Common Language Specification)。它详细定义了一个最小的功能集。任何编译器如果想生成类型兼容于其他“符合CLS,面向CLR语言”生成的组件,那么必须要支持这个最小功能集。下面用一张图来说明彼此间的关系:

什么是IL?

(截自《CLR.via.C#》)

先从上图看一下.net的编译过程,源代码文件经过编译器编译后生成托管模块(managed module)。托管模块说白了就是一个32位(PE32)或64位(PE32+)的PE文件。

具体的结构如下:

PE32或PE32+文件头
CLR头
元数据
IL代码

这里我们着重谈谈IL,IL是与CPU无关的机器语言,比大多数的CPU机器语言都要高级。能访问操作对象类型、创建及初始化对象、调用对象上的虚方法,直接操作数组元素,甚至能抛出和捕捉异常处理,可以说是一种面向对象的机器语言。

什么是JIT?它是如何工作的?

CLR执行托管模块,必须要将IL代码编译成本地CPU指令。这个事情由JIT(just in time)来执行。下面将以一个简单的例子来详细阐述JIT是如何工作的:

static void Main()
{
Console.WriteLine("Hello");
Console.WriteLine("Goodbye");
}

1、CLR在执行Main函数检查引用的所有类型,这里Main用到了Console类,CRL会为此分配一个内部结构。在这个结构中,Console类的所有方法都有对应的入口。

2、Mian首次调用WriteLine函数时,JITCCompiler函数会被调用。JITCCompiler知道是Console类定义了WriteLine函数,并在定义了Console类的程序集中查找WriteLine的IL代码。

3、动态分配一块内存;

4、对找到的IL代码进行验证,然后编译成本地CPU指令,将该指令放到前面动态分配的内存中;

5、修改内部结构中WriteLine函数的入口,使其指向动态分配的内存的地址;

6、JITCCompiler函数跳转到存有本地CPU指令;

7、执行完后,调回Main函数,继续执行后面的代码;

这里需要说明的是,第二次执行WriteLine函数的时候,并没有JIT啥事情了,因为会直接调用内存块中的本地CPU指令。

参考:《分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

《CLR.via.C#》

.NET学习笔记 -- 那堆名词到底是啥(CLR、CLI、CTS、CLS、IL、JIT)的更多相关文章

  1. Android(java)学习笔记82:我们到底该如何处理异常?

    我们到底该如何处理异常? 原则: 如果该功能内部可以将问题处理,用try,自己能解决就自己解决问题. 如果处理不了,交由调用者处理,这是用throws,自己不能解决的问题,我们就抛出去交个调用者解决这 ...

  2. Android(java)学习笔记22:我们到底该如何处理异常?

    1. 我们到底该如何处理异常? (1)原则: 如果该功能内部可以将问题处理,用try,自己能解决就自己解决问题. 如果处理不了,交由调用者处理,这是用throws,自己不能解决的问题,我们就抛出去交个 ...

  3. [C#学习笔记]C#中的decimal类型——《CLR via C#》

    System.Decimal是非常特殊的类型.在CLR中,Decimal类型不是基元类型.这就意味着CLR没有知道如何处理Decimal的IL指令. 在文档中查看Decimal类型,可以看到它提供了一 ...

  4. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  5. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  6. JVM学习笔记-第七章-虚拟机类加载机制

    JVM学习笔记-第七章-虚拟机类加载机制 7.1 概述 Java虚拟机描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被 ...

  7. KTHREAD 线程调度 SDT TEB SEH shellcode中DLL模块机制动态获取 《寒江独钓》内核学习笔记(5)

    目录 . 相关阅读材料 . <加密与解密3> . [经典文章翻译]A_Crash_Course_on_the_Depths_of_Win32_Structured_Exception_Ha ...

  8. EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)

    在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...

  9. JS 学习笔记--9---变量-作用域-内存相关

    JS 中变量和其它语言中变量最大的区别就是,JS 是松散型语言,决定了它只是在某一个特定时间保存某一特定的值的一个名字而已.由于在定义变量的时候不需要显示规定必须保存某种类型的值,故变量的值以及保存的 ...

随机推荐

  1. 如何更改OS系统下截图生成图片格式 jpg pdf

    Mac系统下快速截屏的快捷键: 1.截全屏: shift + command + 3 2.选取截屏 shift + command + 4 生成的图片,系统默认格式忘了,反正不好用,用下面命令更改生成 ...

  2. 封装ios静态库碰到的一些问题(一)

    封装IOS动态库,碰到的第一个问题,就是资源文件的问题,如果将你的程序封装成为静态库,那么静态库中不会包含资源文件和xib文件,这个时候就需要自己封装bundle文件了,而笔者开发环境默认是xcode ...

  3. ORACLE导入、导出命令使用方法

    oracle导入.导出命令使用方法: 给用户增加导入数据权限的操作 第一,启动sql*puls 第二,以system/manager登陆 第三,create user 用户名 IDENTIFIED B ...

  4. 关于echarts3地图下钻省市

    最近关于echarts3弄了个地图下钻,也许是因为运气不好,开始上来需要传递到的城市是成都,结果成都地图(js)加载下来总是挤到了一起,好尴尬,各方实验查找后发现原来是js文件中,成都市地图有个县市并 ...

  5. 【Android UI】:Fragment官方文档

    概述   Fragment表现Activity中UI的一个行为或者一部分.可以将多个fragment组合在一起,放在一个单独的activity中来创建一个多界面区域的UI,并可以在多个activity ...

  6. C#交错数组

    交错数组本质上是一维数组只不过这个一维数组里的元素都是数组.因为该一维数组里面的元素可以是任何大小的数组所以定义时只能以这样的格式定义 ][]; 定义完后必须对该数组进行初始化后方可进行赋值等操作否则 ...

  7. :尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。 ---> System.BadImageFormatException: 试图加载格式不正确的程序。

    iis有程序池有一个属性  是否启用32位应用程序默认是true的特别注意windows2008 服务器系统iis默认的是true 这样发布一下也是必须要做的

  8. PHP, LDAPS and Apache

    要PHP可以连接到用self-signed certificate的ldaps服务器,需要在/etc/ldap.conf中添加一行: TLS_REQCERT     never 要PHP在Apache ...

  9. Sql Servicer 复习笔记(1) 存储过程分布

    第一步:创建表 declare @countInt int declare @age int ) begin ),@countInt), @age,'中国北京') ; ; ) begin ; end ...

  10. 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用

    今天学习了下scala中的链式调用风格的实现,在spark编程中,我们经常会看到如下一段代码: sc.textFile("hdfs://......").flatMap(_.spl ...