CLR via C#读书笔记一:CLR的行模型

 

CLR(Common Language
Runtime)
公共语言进行经常凡一个只是由于余编程语言应用的“进行经常”。

  • 将源代码编译成托管模块

可用支持CLR的旁语言创建源代码文件,然后用相应的编译器检查语法和剖析源代码。无论选择哪个编译器,结果都是托管模块(managed
module)。
托管模块是正式的32号Microsoft
Windows可移栽执行体(PE32)文件,或者是正统的64各Windows可移栽执行体(PE32+)文件,他们都亟需CLR才会尽。(注:PE是Portable
Executable(可移栽执行体)的简称)

本机代码编译器(native code
compilers)生成的是面向特定CPU架构(比如x86,x64或ARM)的代码。相反,每个面向CLR的编译器生成的都是IL(中间用)的代码。

   除了生成IL面向CLR的编译器还要当每个托管模块中生成完全的正数据(metadata)。元数据略地说就是一个数据表集合。一些数据表描述了模块中定义了什么(比如类型及其成员),另一部分叙了模块引用了呀(比如导入的色和成员)。

  Microsoft的C++编译器默认生成包含非托管(native)代码的exe/dll模块,并在运作时操作非托管数据(native内存)CLR即可实行。然而,通过指定/CLR命令行开关,C++编译器就能够挺成包含托管代码的模块。当然,最终用户必须安装CLR才会实施这种代码。在前方提到的有所Microsoft编译器中,C++编译器是举世无双的,只有它才同意开发人员同时写托管和非托管代码,并转移到同一个模块中。它吧是绝无仅有允许开发人员在源代码中而定义托管和非托管数据类型的Microsoft编译器。

  • 拿托管模块合并成程序集

  CLR实际不与模块工作。它同程序集工作。

  首先,程序集是一个要么多只模块/资源文件的逻辑分组。其次,程序集是重用、安全性与版本控制的卓绝小单元。

  

  图中有些托管模块和资源(或数量)文件准备及由一个器处理。工具转代表文件逻辑分组的一个PE32(+)文件。实际有的政工是,这个PE32(+)文件包含一个名为也清单(mainfest)的数据块。清单吧是元数据表的汇聚。这些发明描述了组合程序集的文件、程序集中之文书所实现的明白导出的路以及跟程序集关联的资源还是数据文件。(注:所谓公开导出的种类,就是程序集中定义的public类型,它们在先后集里外部均可见。)

   编译器默认将转移的托管模块转换成程序集。也就是说,C#编译器生成的是包含清单的托管模块。清单指出程序集吸由一个文本构成。对于只有出一个托管模块而且无论是资源(或数额)文件的项目,程序集就是托管模块,生成过程遭到管需实践另外额外的步调。但是,如果期望将同一组文件合并及程序集中,就不能不撑握更多的家伙(比如程序集链接器AL.exe)及那个令行选项。

  • 加载公共语言运行时CLR

  可执行文件(exe)运行时,Windows检查EXE文件头,决定是创建32各还是64个过程之后,会以经过地址空间加载MSCorEE.dll的x86,x64或ARM版本。如果是Windows的x86或ARM版本,MSCorEE.dll的x86版本在%SystemRoot%\System32目录中。如果是Windows的x64版本,MSCorEE.dll的x86版本在%SystemRoot%\SysWow64目录中,64个本则于%SystemRoot%\System32目录中(为了为后相当)。然后,进程的主线程序调用MSCorEE.dll中定义的一个道。这个主意初始化CLR,加载EXE程序集,再调用其输入计(Main)。随即,托管应用程序启动并运行。(PS:微软以64个系统中将有拍卖32位程序的家伙还置身SysWow64目录下,Wow就是Windows
on
Windows的意。而System32目是处理64各程序的。还让32,只是延续了先的叫法,其实应该是64)

  • 行顺序集的代码  

  开发人员一般用c#,VB等高级语言进行编程。它们的编译器将生成IL。然而,和任何任何机器语言一样,IL也克应用汇编语言编写,Microsoft甚至专门供了号称也ILAsm.exe的IL汇编器和称也ILDasm.exe的IL反汇编器。注意,高级语言通常只公开了CLR全部功效的一个子集。然而IL汇编语言允许开发人员访问CLR的全套力量。要清楚CLR具体提供了怎样职能,唯一的法子是读书CLR文档。

  为了施行措施,首先得管办法的IL转换成本机(navive)CPU指令。这是CLR的JIT(just-in-time或者”即经常”)编译器的职责。

哪怕于Main方法执行前,CLR会检测出Main的代码引用的具备项目。这导致CLR分配一个之中数据结构来管理针对性援类型的看。图被Main方法引用了一个Console类型,导致CLR分配一个内部结构。在斯里面数据结构中,Console类型定义的每个方法都产生一个遥相呼应的记录项。每个记录项都蕴含一个地址。根据此地点即可找到办法的实现。对这个结构初始化,CLR将每个记录项都安成(指向)包含在CLR内部的一个勿编档函数。我用拖欠函数称为JITCompiler。

Main方法首不行调整用WriteLine时,JITCompiler函数会让调用。JITCompiler函数负责将艺术的IL代码编译成本机CPU指令。由于IL是”即经常“(just
in time)编译的,所以便以CLR的是组件称为JITter或者JIT编译器。

JITCompiler函数被调用时,它知道凡是设调用的凡哪个方法,以及实际是啊类型定义了拖欠方式。然后,JITCompiler会在概念(该类型的)程序集的排头数据遭到觅被调用方法的IL。接着JITCompiler验证IL代码,并拿IL代码编译成本机CPU指令。CPU指令保存到动态分配的内在块被。然后
,JITCompiler回到CLR为项目创建的内部数据结构,找到与于调用方法对应的那漫长记下,修改最初对JITCompiler的援,使该针对性内在块(其中饱含了刚编译好之本机CPU指令)的地址。最后,JITCompiler函数中过反到内存块中的代码。这些代码正是WriteLine方法(获取单个String参数的好本)的具体贯彻。代码执行完毕并赶回时,会回到Main中的代码,并像过去一律继续执行。

兹,Main要第二浅调整用WriteLine。这同破,由于已对WriteLine的代码进行了征和编译,所以会见直接执行外存块中之代码,完全超越了JITCompiler函数。WriteLine方法执行了后,会另行返回Main。

  •  IL和验证

  将IL编译成本机CPU指令时,CLR执行一个称为也求证(verification)的经过。

  CLR确实供了于一个操作系统中履行的个托管应用程序的力量。每个托管应用程序都在一个AppDomain中实施。每个托管EXE文件默认都当其好的单身地址空间中运作,这个地点空间就发一个AppDomain。然而,CLR的宿主进程(比如IIS或者Microsoft
SQL Server)可控制在一个过程被运行多只AppDomain。

  • 本机代码生成器:NGen.exe

  应用用.NET
Framework提供的NGen.exe工具,可以以应用程序安装到用户的电脑达时,将IL代码编译成本机代码。由于代码在装时既编译好,所以CLR的JIT编译器不需以运作时编译IL代码,这促进提升应用程序的习性。NGen.exe能以以下简单栽情景下发挥举足轻重作用。

  1提高应用程序的启航速度

  2减少应用程序的办事集(所谓工作集,是负于经过的具备内存中,已映射的物理内存那部分(即这些内存全在情理内存中,CPU可以直接访问);进程还有一些虚拟内存,它们或者在更换列表中(CPU不克经过虚拟地址访问,需要Windows映射之后才会访问);还有一对外是磁盘上之分页文件里。)

  NGen.exe生成的文本来以下问题

  1没有知识产权保护

  2NGen生成的文书或者错过共

  3于差之推行时性

  • Framework类库

  FCL(Framework Class
Library)

  • 通用项目系统

  Microsoft制定了一个正式规范来讲述类型的概念及行事,这虽是“通用项目系统”(Common
Type System,CTS)。

  • 国有语言专业

  要创好轻从外编程语言中走访的路,只能打友好
的语言中选择其他具有语言都支持的效果。为了以是上面提供援助,Microsoft定义了“公共语言专业”(Common
Language
Specification,CLS
),它详细定义了一个太小作用集聚。任何编译器只有支持此功能集,生成的类才能够匹配由外符合CLS、面向CLR的语言生成组件。
  (个人的解:CLS是为着不同编程语言中互相调用而计划之,如果单纯所以同栽语言,就不要考虑CLS的正规)

  (说明:文中99%情节来自书本原文。把知识要搬运到这边,只是为方便本人复习、查阅)

相关文章