《CLR via C#》读书笔记(一)——CLR的执行模式
前言
万事开头难,很早之前就想写博客记录些东西,迟迟未行动,甚是遗憾。原因诸多,大体上无非都是懒、没意志力等等。这次从自己的读书笔记开始,兴许能够有所改变。
一、CLR概念
CLR(Common Language Runtime,译为公共语言运行时)是一个可由多种编程语言使用的“运行时”。CLR的核心功能:内存管理、程序集加载、安全性、异常处理和线程同步,可由面向CLR的所有语言(C++、C#、VB、F#等等)使用。无论哪种语言,最后通过编译器的结果都是托管模块。托管模块是PE32文件或PE32+文件,都需要CLR才能执行。
组成部分 | 说明 |
PE32或PE32+头 | 标准windows PE文件头,如果这个头是PE32格式,文件能在Windows32位和64位上运行,如果是PE64,文件只能在Windows的64位上运行。这个头还表示了文件类型,,并包含一个时间标记来指出文件的生成时间。对于只包含IL代码的模块,这些信息大部分都会被忽略。如果是包含本机CPU代码的模块,这个头包含本机CPU代码有关的信息。 |
CLR头 | 包含使这个模块成为托管模块的信息。头中包含要求的CLR版本,一些标志(flag),拖过模块入口方法的元数据token以及模块的元数据、资源,强模块、一些标志以及不太重要的数据项位置/大小 |
元数据 |
每个托管模块都包含元数据表。分为两类: 1、描述源代码中定义的类型和成员。 2、描述源代码引用的类型和成员。 元数据有诸多用途,例如: 1、元数据表面了编译时对原生C/C++和库文件的需求,因为在实现类型/成员的IL代码文件中,已包含有关引用类型/成员的全部信息。编译器直接从托管模块中读取元数据。 2、IDE的“智能感知”能够解析元数据,从而得到一个类型所提供的方法、属性、事件和字段。 3、CLR的代码验证过程使用元数据确保代码只执行“类型安全”的操作 4、元数据允许将对象的字段序列化到内存,将其发送给另一台机器,然后反序列化,在远程机器上重建对象状态 5、元数据允许垃圾回收器跟踪对象生存期,垃圾回收器能判断任何对象的类型并从元数据知道那个对象中的哪些字段引用了其他对象 |
IL代码 | IL代码也被为托管代码,因为CLR管理它到底执行。编译器编译源代码时生成的代码。在运行,CLR将IL编译成本机CPU指令 |
二、程序集执行过程
IL代码是与CPU无关的机器语言,当方法执行时,必须把方法的IL转换成本机CPU命令。下图是方法的首次调用
在执行Main方法前,CLR会分配一个内部数据结构来管理对引用类型的访问,在这个内部数据结构项中,存在与类型中方法对应的一个记录项,这个记录项含有一个地址,可根据此地址找到方法的具体实现。数据结构初始化时,CLR将每个记录项都设置成包含在CLR内部的JITComplier。上图中的WriteLien首次调用时,JITCompiler会被调用,IL将被编译成CPU指令(JIT,即时编译)。当WriteLine第二次调用时,会跳过JITCompiler,直接执行CPU中已有的指令。(注:之前有经常遇到过首次调用某类方法明显比第二次的耗时长,应该与此有关联,因此有时候需要做预加热)。 下图为第二次调用
生成程序集时,有两种模式:Debug和Release。显然,根据词义可知分别是调试模式和发布模式。两者主要区别在于两个C#编译器开关会影响代码优化:/optimize和/debug。Debug含有DEBUG常量,以及不优化代码。Release不包含DEBUG常量,并优化代码。因此Release模式下的程序集相对而言更小,运行更快。
尽管微软做了大量的工作来优化,但运行时的二次编译仍会影响性能,也会分配动态内存。但是.NET FrameWork SDK 配套提供了NGen.exe工具,该工具将所有IL代码编译成本机代码,并将这些本机代码保存到了一个磁盘文件中。NGen.exe能够:1、提高应用程序的启动速度;2、减小应用程序的工作集。纵然NGen.exe工具能够带来不少好处,却并非那么完美,存在如下问题:1、没有知识产权保护 2、NGen生成的文件可能失去同步 3、交叉的执行时性能。因此,在使用NGen.exe工具时要慎重考虑,除非是启动耗时的大型客户端应用程序。
三、Framework类库
.Net Framework包含Framework类库(Framework Class Library,FCL)。FCL是一组DLL程序集的同城,其中包含有数千个类型定义。例如:WEB服务、基于HTML的web窗体/MVC应用程序、“富”WIndows GUI应用程序,Windows控制台应用程序,Windows服务,数据库存储过程,组件库等
四、通用类型系统和公共语言规范
为了令一种编程语言写的代码能与用另一种编程语言写的代码沟通,微软制定了一个正式的规范来描述类型的定义和行为,这既是“通用类型系统”(Common Type System,CTS)。CTS规定,一个类型可以包含零个以上的成员:字段、方法、属性、事件,CTS还指定类型可见性规则以及类型成员的额访问规则:private、family(protected,派生类型访问)、assembly(同一个程序可访问)、public。同时,CTS规定所有类型必须继承System.Object。CTS还有其他规则,不一一列出。
微软定义了“公共语言规范”(Common Language Specification,CLS),详细定义了一个最小功能集,用于不同语言创建的对象可通过COM相互通信,任何支持CLR的编译器都支持这个功能集。
注:程序集执行过程图来源自网络
《CLR via C#》读书笔记(一)——CLR的执行模式的更多相关文章
- CLR via C# 读书笔记-21.托管堆和垃圾回收
前言 近段时间工作需要用到了这块知识,遂加急补了一下基础,CLR中这一章节反复看了好多遍,得知一二,便记录下来,给自己做一个学习记录,也希望不对地方能够得到补充指点. 1,.托管代码和非托管代码的区别 ...
- 《Head First 设计模式》读书笔记(1) - 策略模式
<Head First 设计模式>(点击查看详情) 1.写在前面的话 之前在列书单的时候,看网友对于设计模式的推荐里说,设计模式的书类别都大同小异,于是自己就选择了Head First系列 ...
- CLR via C# 读书笔记---常量、字段、方法和参数
常量 常量是值从不变化的符号.定义常量符号时,它的值必须能在编译时确定.确定后,编译器将唱两只保存在程序集元数据中.使用const关键字声明常量.由于常量值从不变化,所以常量总是被视为类型定义的一部分 ...
- Clr Via C#读书笔记---I/O限制的异步操作
widows如何执行I/O操作 构造调用一个FileStream对象打开一个磁盘文件-----FileStream.Read方法从文件中读取数据(此时线程从托管代码转为本地/用户模式代码)- ...
- Clr Via C#读书笔记---计算限制的异步操作
线程池基础 1,线程的创建和销毁是一个昂贵的操作,线程调度以及上下文切换耗费时间和内存资源. 2,线程池是一个线程集合,供应你的用程序使用. 3,每个CLR有一个自己的线程池,线程池由CLR控制的所有 ...
- Clr Via C#读书笔记---CLR寄宿和应用程序域
#1 CLR寄宿: 开发CLR时,Microsoft实际是将他实现成包含在一个dll中的COM服务器.Microsoft为CLR定义了一个标准的COM接口,并为该接口和COM服务器分配了GUID.安装 ...
- Clr Via C#读书笔记---程序集的加载和反射
#1 加载程序集 Assembly.Load: public class Assembly { public static Assembly Load(AssemblyName assemblyRef ...
- Clr Via C#读书笔记---垃圾回收机制
#1 垃圾回收平台的基本工作原理: 访问一个资源所需的具体步骤: 1)调用IL指令newobj,为代表资源的类型分配内存.在C#中使用new操作符,编译器就会自动生成该指令.2)初始化内存,设置资源的 ...
- Clr Via C#读书笔记---线程基础
趣闻:我是一个线程:http://kb.cnblogs.com/page/542462/ 进程与线程 进程:应用程序的一个实例使用的资源的集合.每个进程都被赋予了一个虚拟地址空间. 线程:对CPU进行 ...
- CLR via C# 读书笔记 6-2 不同AppDomain之间的通信 z
跨AppDomain通信有两种方式 1.Marshal By reference : 传递引用 2.Marshal By Value : 把需要传递的对象 通过序列化反序列化的方式传递过去(值拷贝) ...
随机推荐
- VUE-利用OSS BrowserJS-SDK实现阿里OSS前端上传
项目中遇到利用阿里OSS上传文件,线上很多示例用到了各种SDK,却没有看到OSS BrowserJS-SDK相关示例,鉴于脑子不好使,记一下. 封装upload相关组件  使用npm安装SDK的开发 ...
- 在阿里云ECS CentOS7上部署基于MongoDB+Node.js的博客
前言:这是一篇教你如何在阿里云的ECS CentOS 7服务器上搭建一个个人博客的教程,教程比较基础,笔者尽可能比较详细的把每一步都罗列下来,包括所需软件的下载安装和域名的绑定,笔者在此之前对Linu ...
- 去掉input在type="number"时右边的上下箭头
加了代码之后: input::-webkit-outer-spin-button, input::-webkit-inner-spin-button{ -webkit-appearance: none ...
- Java作业五(2017-10-15)
/*3-6.程序员;龚猛*/ 1 package zhenshu; import java.util.Scanner; public class text { public static void m ...
- Lock、ReentrantLock、ReentrantReadWriteLock区别
Lock Lock相比于synchronized具有更强大的功能,在jdk1.6之前,锁竞争激烈的情况下使用lock的实现类ReentrantLock甚至比synchronized具有更好的性能,1. ...
- 【DFS】素数环问题
题目: 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,输出时从整数1开始,逆时针排列.同一个环应恰好输出一次.n<=16 如输入: 6 输出: 1 4 3 2 5 6 1 6 5 ...
- [Swift]LeetCode850. 矩形面积 II | Rectangle Area II
We are given a list of (axis-aligned) rectangles. Each rectangle[i] = [x1, y1, x2, y2] , where (x1, ...
- Redis 设计与实现 (二)--数据库
typedef struct redisDb { dict *dict; /* The keyspace for this DB */ dict *expires; /* Timeout of key ...
- 微信小程序自动化测试实践
由于腾讯系QQ.微信等都是基于腾讯自研X5内核,不是google原生webview(其实就是进行了二次定制).实质上也是混合应用的一种,现在很多app产品也开始流行采用X5内核作为其内嵌web浏览服务 ...
- CentOS安装gcc clang git mysql等软件高版本福利
最近同事需要在单位提供的开发机上临时安装gcc等软件,时间紧迫,因此向其推荐安装福利devtoolset. 感谢devtoolset,使得CentOS软件安装无比的快捷,卸载也是无与伦比的简单. gc ...