欢迎光临
我们一直在努力

CLR系列一:CLR的执行模型

1. .NetFramework包含CLR(公共语言运行库)和FCL(类库:Framework Class Library),所以运行开发的程序需要安装.Netframwork

 

2.源代码—>生成多个托管模块(中间语言IL和元数据)—>生成一个程序集又叫组件(dll)

   源代码经过编译器编译后生成多个托管模块,多个托管模块和一些资源文件经过编译器生成一个程序集(组件)

   托管模块由中间语言(托管代码)和元数据构成,元数据由“定义类型和成员”表和“引用类型和成员”表构成

   程序集中包含了一张叫做“清单”的模块,它记录了构成程序集模块构成的信息包括资源文件。

   其中程序集还包含一些关于需要引用自己的信息。

   注意:CLR直接与程序集一起工作,并不和托管模块一起工作。

    托管代码经过CLR的处理最后生成的就是能让CPU直接操作的指令和数据。

 

3.我们共建的程序集即可以使一个单独的可执行应用程序(.exe)也可以使一个DLL(一系列由可执行程序使用的类型),这些最终都是CLR来管理执行。(生成CPU的指令)

 

4.IL(中间语言或者说托管代码):可以把它看成是面向对象的机器语言。C#,VB.NET,J#等众多语言经过编译器生成后都是IL,同时我们可以用汇编来编写IL。我们通常运行程序的时候是把IL编译成CPU可识别的机器指令。这时我们就要用到CLR的JIT编译器(just in time),及时编译器。

 

5.程序调用一个函数CLR做的工作举例

  在主函数使用:console.writlne(“Hello”);首先CLR会检测主函数中的所有类型,他将分配一个内部的数据结构,它用来管理对引用类型的访问。在这个例子中CLR发现了console类,为它分配一个内部结构,然后把console类的每个方法记录在这个结构中,每条数据都有一个地址,根据地址可以找到方法的实现,当首次调用writlne时,CLR将在程序集中找到IL并编译成本地CPU可识别的指令。当同一个函数被CLR编译的时候,其实在第一次编译的时候已经把它编译成CPU指令放在了动态内存库中了,以后的不会再编译,只需调用即可,因此只有在第一次编译的时候才会有性能的损耗,但是CLR有优化,这点不需要大量的考虑。

 

6.托管代码和非托管代码(C,C++)的区别;对于非托管代码是针对特定的CPU平台编译好的。在调用的时候,代码能直接执行。而在托管环境中,代码的编译分2部分进行。首先由编译器生成IL(中间代码或者说托管代码),,但IL代码并不能被CPU识别运行,我们需要把IL代码在运行的时候转换成CPU指令,因此在第二个阶段(也是在运行阶段)需要对IL进行转化,这样就需要额外的动态内存和CPU。(对于非托管代码在编译的时候已经被编译成CPU可识别的指令,这样相对于托管代码就节省了大量的CPU和内存)。

 

7.平时我们在开发时候用DUG模式,在发布的时候用release,因为后者创建的IL代码和JIT代码质量都优化了,但缺点是调试麻烦。

 

8.CLR的JIT优势:JIT能智能的判断当前的代码运行在什么CPU平台上,根据判断生成对应的CPU指令,这样能做大限度的利用CPU的指令功能。而非托管代码则只能用最小集合的CPU指令(对于不同的CPU平台生成的指令可能不蒙运行,因此只能选择公共的指令结合)。并且CLR能评估代码代码的执行,并将IL重新编译成本带代码。它在重新编译IL的时候已经重新组织了带代码,这样减少了很多不必要的指令。在运行时,一旦加载一个程序集,CLR就会判断是否存在该程序集的一个预编译版本(也就是以前编译过),如果存在则不需要在编译,直接调用原来编译好的代码。

 

 9.IL通过CLR生成的指令对于CPU不会去分辨是32位还是64位,这样就对CPU进行了抽象。但是IL代码的优点不再此处,而是在代码的安全性和可靠性。因为在生成CPU指令的时候CLR会去执行一个验证过程,这个过程会去检验高级高级的IL代码,而验证的过程中用到了托管模块的元素据。(托管模块=托管代码+元素据)这样在验证的过程中可以确定代码不会访问非法模块。

 

10.对于IL代码是不安全的,我们可以用反编译IL工具对原IL代码进行反编译,生成自己需要的代码。但是一般情况下我们的DLL文件放在服务器,外部人员是无法获取到的,但是以防万一,我们可以把一些机密的算法或者代码用非托管代码来编写,这样将直接生成CPU的本地指令,而不是IL代码和元数据。这样保证一定安全的前提是别人不会对CPU指令进行反编译。

 

 11.其实.NetFrameWork就是一系列的DLL构成的,我们平常用的一些方法都是应用类型的,是微软针对某个具体的场合创建的DLL,但是我们现在去掉了某个场合,深入到具体的平台来了解程序的本质。

 

12.多种语言编写的代码能互相调用,目的就是CLR是围绕类型展开的。由于类型是CLR的标准,所以通用类型系统(CTS)诞生,它描述了类型的定义和行为方式。其中我们把CTS和.NetFrameWork合并的展示出来后就形成了我们所说的“公共语言基础”(CLI)

 

13.公共语言规范(CLS),一方面COM允许使用不同语言创建的对象进行通信,另一方面CLR集成了多语言,并允许在一种语言中调用另一种语言的对象。之所以能实现这样的集成,是因为CLR建立了标准的类型集,元素据以及公共执行环境。由于语言之间存在差别,比如大小写等,为了实现语言间生成的代码互相操作不出现问题,因此CLS出现了,它定义了所有至此CLR语言的所有类型的并集,相当于CLR和CTS包含了所欲语言类型,比如C#,VB等,然后C#和VB的并集又包含了CLS,所以当编写的程序只要支持CLS就能支持所有的语言,也就能是各个语言间进行通信和对象调用。对于C#,VB或其他开发人员,语言本身只提供了CLR和CTS的一部分,只有汇编语言才开放了所有的CLR和CTS的类型。

 

14.一个类型的每个成员,要么是一个字段,要么是一个方法,对于某种语言它提供了额外的抽象,比如C#它提供了枚举,数组,属性,索引,委托,事件,构造器,终结器,操作符重载等概念,当这些遇到编译的时候会被转换成字段或方法,使其他的编程语言能够访问这些。(可以用IL反编译器在元素据中查看生成的字段和方法)

 

 

 

 

 

 

 

 

 

赞(0)
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:CLR系列一:CLR的执行模型
文章链接:https://www.jmwz.net/1529.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址