初识CLR
眨眼间我已经实习了半年时间并且转正了,身份也正式从一个学生转变为一个职场人,这个博客自从开始实习以来就一直没有更新过= =没错,就是我懒癌晚期,不过不行!一切都要开始走向正轨,此博会继续见证我的成长,从现在开始吧!
最近刚开始看CLR via C#这本神作,本来以为自己会看不懂,之前我对这本书一直是“远观不可亵玩”的态度,当真正看了之后才发现许多事木有有你想象的那么难嘛~好,开始正文。
CLR,又叫通用语言运行时,又叫Common Language Runtime,你可以把他看作是一个虚拟机。来,咱先来看一个很经典的.NET Framework结构图:

我们按照层级关系一层层来看
第一层:
我们最熟悉的编程语言,.NET目前已经支持超过70中编程语言了,只要是.NET支持的编程语言都能享受CLR所带来的便利和优势。
第二层和第三层一起讲:
汇编器,这里的编译器指的不是通常意义的编译器,通常意义指的编译器是指可以直接将高级语言转换成目标机器语言,而这里的汇编器指的是将.NET支持的编程语言编译成托管代码(第三层)。那么问题来了。。。托管代码是什么鬼?可以这么理解,如果说.NET编译器生成的是托管代码,那我们平时学习的C/C++,编译器生成的就是非托管代码。托管代码包含IL和元数据(我擦。。。怎么又多了两个名词),IL指的是微软定义的中间语言(MSIL,Microsoft Intermediate Language,你可以理解为从高级语言到目标机器语言中间的一种代码)。CLR必须知道代码中的数据类型、类和他引用的类型和类的定义才能加载代码、管理内存、执行方法,所以这些信息就叫做metadata。所以第二道第三层的过程就简单的理解为把高级语言编译成中间语言即可。
第四层:
在这一层,CLR提供了运行时非常重要的一个环节即将中间语言编译成目标机器语言的功能。这里我们举个例子再来看一幅图深入讨论一下:

上图展示了一个方法首次调用时发生的事情,在Main方法执行之前,CLR会检测出Main代码所有的引用类型。CLR就会构造像右边那样的一个数据结构,里面是一些方法中用到的引用。这里存着每一个方法的入口,比如Console类中有WriteLine(),WriteLine(string)等,然后CLR会将其进行初始化,将这些入口指向一个未编档函数。这个函数就是JITCompiler。
当Main方法首次调用WriteLine时,JITCompiler会被调用,首先JIT会先申请一块稍后会用到的内存块,然后JITCompiler会在程序集的元数据中找到被调用方法的IL,并将将IL编译成本机的目标代码放入事先分配好的内存当中,接着JIT会修改最初调用它的这个引用指向之前分配好的内存并执行它,最后JIT会回到源代码继续执行下一条语句。这样一来,当Main方法之后再访问这个方法时就会直接去调用本机代码。所以这也是c#到底属于解释型还是编译型语言之争的源头,因为他是在执行的时候才去生成最终的目标代码的。讲到这里,许多人要开始质疑了,托管代码在运行时多了JIT这一步,而非托管代码是直接执行的目标代码,这效率肯定差一大截吧?事实并非如此,微软已经把JIT对性能的影响降到了最低,下面列举了托管代码由于非托管代码的一些地方:
- 当JIT生成本地代码时会根据当前硬件环境去使用当前cpu最优的指令,简单的来说就是根据不同cpu会做代码优化。
- JIT在代码运行时能够检测到代码运行的情况并分析进一步优化代码,比如CLR检测到一个if分支在99%的情况下是true,那么JIT就会重新编译,达到进一步的代码优化。(这一点据说还没有完全实现?有待考证,有知道的可以评论)
嗯。。今天要讲的差不多讲完了


初识CLR的更多相关文章
- CLR学习之初识CLR
一.什么是CLR? CLR即公共语言运行时(Common Language Runtime,简称CRL),就是微软为.net产品构建的运行环境,与java的JVM类似,通俗的讲就是.net虚拟机.CL ...
- Python开发【第一篇】:初识Python
初识python 一.python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解 ...
- Python开发【第二篇】:初识Python
Python开发[第二篇]:初识Python Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...
- CLR via C#(16)--泛型
泛型就像是一个模板,常常定义一些通用的算法,具体调用时再替换成实际的数据类型,提高了代码的可重用性. 一.初识泛型 1. 简单实例 以最常用的FCL中的泛型List<T >为例: stat ...
- CLR via C#(14)-可空值类型,关于?和??的故事
我们都知道,值类型是不能为Null的,但是在实际应用中有些情形却需要将值类型置为null.因此,CLR中引用了可空值类型的用法.今天的文章中见到最多的符号估计就是?了吧. ?——初识可空值类型 1. ...
- CLR via C# 提纲
第I部分 CLR基础第1章 CLR的执行模型 31.1 将源代码编译成托管模块 31.2 将托管模块合并成程序集 61.3 加载公共语言运行时 81.4 执行程序集的代码 101.4.1 IL和验证 ...
- [CLR via C#]17. 委托
回调函数是一种非常有用的编程机制,它已经存在很多年了.Microsoft .NET Framework通过委托(delegate)来提供一种回调机制.不同于其他平台(比如非托管C++)的回调机 ...
- C#脚本引擎 CS-Script 之(一)——初识
最近在做新产品,这个产品需要满足不同项目对于系统的定制性数据处理需求,比如有的要统计一段时间内某开关打开关闭了多少次,有的要统计一段时间内空调的使用率,有的希望根据温度来控制空调的开还是关,有的则是希 ...
- Python初识与简介【开篇】
目录 1.扯淡 2.Python历史 3.Python简介 4.Python应用 5.为什么是python而不是其他语言? 6.Python的种类 7.Python的特点 8.Python设计哲学 9 ...
随机推荐
- PHP实现对MongoDB的基础操作
PHP扩展 PHP5.2.PH ...
- CSS3 @font-face (webfont)
先大概介绍下计算机领域常见的字体类型与格式. 点阵字体(Bitmap Font)点阵字体也叫位图字体,其中每个字形都以一组二维像素信息表示.这种文字显示方式于较早前的电脑系统(例如未有图形接口时的 D ...
- 在Ajax中将数组转换成字符串(0517-am)
一.如何在Ajax中将数组转换成字符串 1. 主页面; <head> <meta http-equiv="Content-Type" content=" ...
- HTML5比较实用的代码
增强IE兼容性 <!--[if IE]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js&q ...
- .net core3
- 在jsp页面中使用自定义标签
在某些场景中,自定义标签可封装大量代码,使页面变得更简洁,标签也可以很方便地在不同页面中实现通用而不必去粘贴大量的js代码.现在把最近做的一个自定义标签在这里总结一下.首先总结一下关于自定义标签的一些 ...
- Lazy Load Plugin for jQuery延迟加载测试成功
一直需要的功能,网页图片太多时对于降低网络流量超有用. 最新的V1.9.3版本其实已不用修改就可以起作用了. 不用网上说的要自己修改代码.
- Qt信号和槽的个人总结
1.connect connect(sender,SIGNAL(signal()),receiver,SLOT(slot())); 这里用到了两个宏:SIGNAL() 和SLOT():通过connec ...
- 黑马程序员_Java面向对象_包
7.包 7.1包(package) 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称是:包名.类名. 包也是一种封装形式. 利用命令行自动生成文件夹格式:D:\jav ...
- Go语言的构建方法总结
趁着近期要换工作的空闲时间,看了一下Go语言,与C++相比,Go语言的确在不少地方轻便了不少,例如:增加了内置的字符串类型.多个返回值.支持协程.简单的构建方法等等.使得在生产效率方面有了不少的提高. ...