好吧,废话少说,先上一章Hello World图:

我们有了一个Hello world程序,如此之简单,再加上我今天没有用汉字编程o(>﹏<)o,所以一切很简单明了。

故事开始:

编译:

一个程序写完肯定要编译,以前什么C啊什么的都是编译成本机的CPU指令,但是我们的C#不是。

C#,VB.NET都会把它们编译成托管模块,托管模块在一个标准的可移植的PE文件中。(那些懵懂的少年肯定慌了,这是什么鬼,又是托管模块又是PE文件的。莫慌,所有你听不懂的高大上的术语其实都很简单,你现在不需要懂,听我慢慢道来)

所谓PE文件,就是可移植执行体,简单来讲就是.EXE和.DLL这种鬼东西(这个exe和C语言生成的有区别的)。这个PE文件里的托管模块,你可以当做一个对象,对象里有四个属性,一个PE头(描述文件),一个CLR头(描述这个对象的整体的一些信息,比如main入口),元数据(这个很关键,一种元数据表包含源代码中定义的那些那些类型和成员的描述信息,另一种包含引用的类型和成员的描述信息),IL代码(就是你的源代码被编译后的代码,又称中间语言)。

如果觉得麻烦,前面两个属性你可以忘掉了,记住后面两个就好:元数据和IL代码(简单来讲,就是代码的描述信息和编译后的代码)。

但是一个PE文件可不只一个托管模块,它可以由几个托管模块组成。编译器会把多个托管模块和资源文件合并成一个包含清单的程序集,这才是最后的PE文件。

运行:

但是这个托管模块也就是PE文件并不能直接运行,他需要CLR。

CLR常用简写词语,CLR是公共语言运行库(Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集等),并保证应用和底层操作系统之间必要的分离。CLR存在两种不同的翻译名称:公共语言运行库和公共语言运行时。

此描述及以后的描述均来自百度百科,我懒得手打。

CLR的核心功能包括:内存管理,程序集加载,安全性,异常处理和线程同步。

这个东西又称为公共语言运行时。

前面的说到不能直接运行的时候,这里有懵懂的少年肯定说,我生成的exe文件明明可以直接运行。

这是因为你的电脑上安装了.NET Framework。当你在打开exe程序的时候你的进程的主线程会调用MSCorEE.dll的一个方法,这个方法会初始化CLR,再加载exe程序集,然后调用入口方法即main函数。

所以说实际上你的代码运行是需要在CLR上的。

那么CLR到底是怎么玩我们的Hello world的?

它会在运行时编译我们的IL代码。(先别吐槽为什么要编译两次,后面有讲)

早在Main函数执行之前,CLR就会检测Main的代码所引用的所有类型,然后生成了一个内部的数据结构来管理引用类型的访问。

在这个内部结构中,每个类型比如Console的每个方法都会有一个入口,每个入口都有一个地址(这里叫地址A吧),这个地址A就可以找到方法的实现代码。

而在这个内部数据结构初始化的时候,所有的这些入口的地址都会被设置成一个叫JITCompiler的函数。

就比如上面图中的hello world代码第一句,CLR在执行这句代码的时候会跑进JITCompiler这个函数中,这是内部操作:

  1. 会跑进托管模块,然后根据元数据匹配类名和方法名,获取你要执行的Console这个类里面Writeline这个函数在IL代码里面的地址B。
  2. 然后编译这段IL代码变成本机的CPU指令放到一块内存空间中,地址为C。(在这个编译之前还会进行验证哦,验证这个IL代码是否安全)
  3. 接着修改元数据中地址A的值变为地址C的值。
  4. 最后跳转到地址C开始执行地址C的cpu指令。

那么如果我们第二次去执行Writeline函数呢?此时内部结构中Writeline函数入口的地址指向的已经是编译好的CPU指令的地址了,所以也就不会去执行JITCompiler这个函数。

千万不要认为这样一定会很慢哦,除了第一次运行时JITCompiler的编译可能需要花费掉编译和优化的时间,后来执行的就是本地CPU指令哦。再加上JITCompiler的这个编译会根据你的机器的CPU不同可能会去生成一些专属于本CPU的特殊指令去优化IL代码,有的这种托管程序可能还要比非托管程序快。

好了,本章的精髓就是上面这些了。

现在我们想想为什么要编译两次?

因为这样的话,无论用C#、VB、F#这些东西你都可以生成一样的包含IL代码的托管程序集,然后这个托管程序集在CLR上运行,也就是说可以混合写代码,一个C#代码可以调用VB代码的DLL,用最适合的语言做最适合的事情。

并且在CLR监视之下执行的IL代码因为在执行前会进行安全校验,所以会提高程序的健壮性和可靠性。

【C#进阶系列】01 CLR的执行模型——一个Hello World的故事的更多相关文章

  1. 01.由浅入深学习.NET CLR 基础系列之CLR 的执行模型

    .Net 从代码生成到执行,这中间的一些列过程是一个有别于其他的新技术新概念,那么这是一个什么样的过程呢,有什么样的机制呢,清楚了这些基本的东西我们做.Net的东西方可心中有数.那么,CLR的执行模型 ...

  2. 01.CLR的执行模型

    在非托管的C/C++中,可以进行一些底层的操作     "公共语言运行时"(CLR)是一个可由多种编程语言使用的"运行时"          CLR的核心功能包 ...

  3. C#进阶系列 ---- 《CLR via C#》

      [C#进阶系列]30 学习总结 [C#进阶系列]29 混合线程同步构造 [C#进阶系列]28 基元线程同步构造 [C#进阶系列]27 I/O限制的异步操作 [C#进阶系列]26 计算限制的异步操作 ...

  4. JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数

    本篇体验JavaScript事件的基本面,包括: ■ 事件必须在页面元素加载之后起效■ 点击事件的一个简单例子■ 为元素注册多个点击事件■ 获取事件参数 ■ 跨浏览器事件处理 □ 事件必须在页面元素加 ...

  5. JavaScript进阶系列01,函数的声明,函数参数,函数闭包

    本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...

  6. CLR 的执行模型(2)

    第一章 CLR 的执行模型(2) 本篇内容大纲 Framework 类库(Framework Class Library , FCL) 通用类型系统(Common Type System,CTS) 公 ...

  7. 第一章 CLR 的执行模型

    CLR via C# 读书笔记:第一章 CLR 的执行模型(1) 第Ⅰ部分CLR基础.这部分为三章(第一章:CLR的只想能够模型,第二章:生成.打包.部署和管理应用程序及类型,第三章:共享程序集和强命 ...

  8. [.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序

    [.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序   一.练习项目: http://www.asp.net/mvc/tutorials/mvc-4/gettin ...

  9. 第一部分 CLR基础:第1章 CLR的执行模型

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

随机推荐

  1. 由于源码使用是c\c++与oc混编导致Unknown type name 'NSString'

    今天看到个问题,编辑工程提示Unknown type name 'NSString',如下图 解决方案三: 将Compile Sources As 改为 Objective-C++

  2. SQL Server への接続を許可するファイアーウォール設定

    netsh advfirewall firewall add rule name="SQL Server Browser" protocol=UDP dir=in localpor ...

  3. 用git上传本地项目到github上

    首先确认自己已经安装了git,打开git bash,输入ssh-keygen -t rsa -C "自己的邮箱地址@XXX.com" ,生成自己的公钥与私钥   一路默认回车,会生 ...

  4. Spring3系列5-Bean的基本用法

    Spring3系列5-Bean的基本用法 本篇讲述了Bean的基本配置方法,以及Spring中怎样运用Bean. 主要内容如下: 一.      Spring中Bean的相互引用 二.      Sp ...

  5. windbg常用命令

    SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols CPU常用命令 载入sos.dll  执行.load C:\Windows\Micr ...

  6. Spark和hadoop的关系

    1. Spark VSHadoop有哪些异同点? Hadoop:分布式批处理计算,强调批处理,常用于数据挖掘和数据分析. Spark:是一个基于内存计算的开源的集群计算系统,目的是让数据分析更加快速, ...

  7. 正则表达式工具RegexBuddy使用教程(原创自Zjmainstay)

    从<我眼里的正则表达式(入门)>这个文章,到<深入正则表达式应用>,再到后来专门创建的正则QQ群"专精正则表达式",到现在已经过去2年时间了.在文章和群里一 ...

  8. iOS 复选框做法

    -(void)checkboxClick:(UIButton *)btn{    btn.selected = !btn.selected;} - (void)viewDidLoad {UIButto ...

  9. 【团购活动】接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!

    接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!http://bbs.eeworld.com.cn/forum.php?mod=viewthread& ...

  10. MyBatis知多少(11)企业数据库

    企业数据库比应用程序数据库更大,其外部影响也更大.它们与其他系统之间存在更多的关系,包括依赖关系和被依赖关系.这些关系可能是Web应用程序与报表工具之间的,但也很有可 能是与其他的复杂系统和数据库的接 ...