clr基本

  CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”。(例如:c#,c++/cli,vb,f#,ironpython,ironruby,il...)

  CLR的核心功能内存管理、程序集加载、安全性、异常处理、线程同步、泛型、尾调用指令和基本的公共语言基础结构 (CLI) 类型系统等。

  托管模块是一个标准的32位microsoft windows可移值执行体pe32文件(64位系统为pe32+),他们需要clr才能执行。

  托管的程序集总是利用windows的数据执行保护和地址空间布局随机化,这2个功能旨在增强整个系统的安全性。

  托管模块的组成部分:pe32(或pe32+)头,clr头,元数据,il中间代码。  

  本地代码编译器生成的是面向特定cpu架构的代码。相反每个面向clr的编译器生成的都是il代码。

 源代码文件----》编译器----》托管模块

  

  加载CLR

  .net framework sdk提供了名为clrver.exe的命令行使用程序,它能列出一台机器上安装的所有clr版本。

  c#编译器可以指定一个平台(基于x86 windows,x64 windows或者ia64 windows).net4.0之前默认anycpu,4.0 exe项目默认x86

  如果一个非托管应用程序调用loadlibrary来加载一个托管程序集,windows会自动加载并初始化clr,以便处理程序集中的代码。

  

  执行clr

  托管程序集同时包含元数据和il。il是与cpu无关的机器语言。il比大多数cpu机器语言都要高级。il也能使用汇编语言来写。

  为了执行一个方法,首先必须把它的il转换为本地cpu指令。这是clr的jit编译器的职责。

  首次执行托管exe---->jitcompiler---->查找方法、从元数据中获取il、分配内存块、编译cpu指令、修改方法对应的记录项、跳转内存块中的本地代码

  第二次执行托管exe跳过jitcompiler直接跳转内存块中的本地代码

  对于大多数应用程序,因jit编译造成的性能损失并不显著,而且clr的jit编译器会对本地代码进行优化,优化后的代码会获得更出色的性能。

  c#调试产生的pdb文件就是帮助调试器查找局部变量并将il指令映射到源代码。

  release版本就是让发布程序经过jit优化,所以线上项目最好都以release版本发布

  clr提供一个在操作系统进程中执行多个托管应用程序的能力。每个托管的应用程序都在一个appdomain中执行。

  IL

  IL是基于栈的。

  微软提供ilasm.exe的il汇编器和一个名为ildasm.exe的il反汇编器。  

  IL指令是无类型的(typeless)

  IL最大的优势并不在于它对底层CPU的抽象,而是应用程序的健壮性和安全性。

  FramWork

  framework class library是一组dll程序集的名称,其中包含数千个类型定义,每个类型都公开了一些功能。

  通用类型系统(common type system)描述了类型的定义和行为。一个类型可以包含另个或者多个成员。

  公共语言运行规范(common language specification)详细定义了一个最小功能集。任何编译器生成的类型要向兼容于由其他符合cls面向clr的语言所生成的组件,就必须支持这个最小功能集

  

  响应文件

  响应文件是一个文本,其中包含了一组编译器命令行开关。执行csc.exe时,编译器会打开响应文件,并使用其中包含的所有开关,感觉就像是这些开关直接在命令行传递给csc.exe。

  响应文件能带来很多方便,因为不必每次在编译项目时,都手动指定需要的命令行参数。

  c#编译器允许同时指定多个响应文件。

  

  程序集

  程序集是一个抽象的概念,clr实际上不和模块一起工作,而是和程序集一起。

  程序集是一个或多个模块/资源文件的逻辑分组。是重用、安全性以及版本控制的最小单元。在clr中相当于一个“组件”

  托管模块(il+元数据)+资源文件 ----》编译器----》程序集

  默认情况,编译器会把生成的托管模块转换成程序集。

 对于一个可重用的、可保护的、可版本控制的组件,程序集把它的逻辑表示和物理表示区分开。

  在程序集的模块中还包含与引用的程序集有关的信息(例如版本号)。这些信息使程序集可以自描述。换句话说,clr能判断出为了执行程序集中的代码,程序集中得依赖对象是什么。不需要在注册表或active directory domain services中保存额外的信息。

  程序集的所有文件中,有一个文件容纳了清单。清单也是一组元数据表的集合,表中主要包含了作为程序集的组成部分的文件的名称。

  可用单独的文件对类型进行划分、可在自己的程序集中添加资源或者数据文件、程序集包含的各个类型可以用不同的编程语言来实现。

  元数据

 元数据是一组数据表。其中的一些数据表描述可模块中定义的内容,比如类型及成员。还有一些元数据描述了托管模块引用的内容,比如导入的类型及成员。

  元数据是一些老技术的超集,这些老技术包括com的“类型库”和“接口定义语言”文件。

  元数据总是嵌入和代码相同exe/dll文件中。

  元数据的用途:编译时元数据消除对本地c/c++头和库文件的要求,vs使用元数据帮助你智能感知代码,类型安全验证,序列化,gc管理。  

  元数据是一个二进制数据块,由几个表构成。这些表分为3个类别:定义表、引用表和清单表。

  定义表:moduledef,typedef,methoddef,fielddef,paramdef,propertydef,eventdef

  引用表:assemblyref,mouduleref,typeref,memberref

  清单表:assemblydef,filedef,manifestresourcedef,exportedtypesdef

  程序集还讲语言文化作为其身份标识的一部分。没有指定具体语言文化的程序集称为语言文化中性。

  部署

  程序集的打包没有任何特殊需求。不需要对注册表进行任何修改,clr就可以在应用程序的目录中查找引用的程序集。

  也可以使用其他机制来打包和安装程序集文件,比如使用.cab文件。还可以将程序集文件打包成一个msi。

  msi文件可实现程序集的“按需安装”,在clr首次尝试加载程序集的时候才安装这个程序集。

  部署到和应用程序相同的目录中得程序集称为私有部署的程序集,这是因为程序集文件不和其他任何应用程序共享(除非其他应用程序也部署到这个目录中)。

  clr尝试定位一个程序集文件时,总是先在应用程序基目录中查找。如果没有找到,就会扫描几个子目录。

  对于可执行应用程序(exe),配置文件必须在应用程序的基目录中,而且必须采用exe文件的全名作为文件名,再加一个.config扩展名

  对于microsoft asp.net web窗体应用程序,文件必须在web应用程序的虚拟根目录中,而且总是命名为web.config   

  

  共享程序集与强命名程序集

  弱命名程序集与强命名程序集都是c#编译器或者al.exe产生。他们的区别在于强命名程序集使用发布者的公钥/私钥对进行了签名,它唯一性地标识了程序集的发布者。

  一个程序集可以采取两种方式来部署:私有或全局。弱命名程序集只可以私有部署。

  可以使用sn.exe来生成公钥/私钥对。

  全局程序集缓存

  如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且clr在检测到对该程序集的一个引用时,必须知道自动检查该目录。这个已知的位置成为全局程序集缓存(GAC)。

  GAC通常位于c:\windows\assembly目录下(假定windows安装到c:\windows目录)

  可以使用GACUtil.exe在GAC中安装一个强命名程序集

  GAC目录是结构化的:其中包含许多子目录,并用一个算法来生成这些子目录的名称。

  CLR解析引用类型

  CLR先加载并初始化程序集,然后读取clr头,查找标识应用程序的入口方法的methoddeftoken。然后clr会检索methoddef元数据表,找到该方法的il代码在文件中的偏移量,把这些il代码jit编译成本地代码。编译时会对代码进行验证以确保其类型安全性。最后执行本地代码。

  clr可以在三个地方找到类型:同一个文件(早起绑定)、不同的文件但同一个程序集(当前程序集清单目录)、不同的文件不同的程序集(其他程序集清单目录)。  

  对于clr来说,所有程序集都是根据名称、版本、语言文化和公钥来标识的。

  GAC根据名称、版本、语言文化和cpu架构来标识程序集。

  类型基础

  所有类型都是从system.object派生

  system.object提供4个公共实例方法equals,gethashcode,tostring,gettype。

  system.object提供2个受保护方法memberwiseclone,finalize.

  clr要求所有对象都用new操作符来创建。

  new操作符所作的事情:1.它计算类型及其所有基类型中定义的所有实例字段所需的字节数。堆上的每个对象都需要一些额外的成员--“类型对象指针”和“同步块索引”。这些成员由clr用于管理对象。这些额外成员的字节数会计入对象大小。2.它从托管堆中分配指定类型要求的字节数,从而分配对象的内存,分配的所有字节都设为零。3.它初始化对象的--“类型对象指针”和“同步块索引”成员。4.调用类型的实例构造器,向其传入在对new的应用中指定的任何实参。

  clr最重要的特性之一就是类型安全性。在运行时,clr总要知道一个对象是什么类型。调用gettype方法,总是知道一个对象确切的类型是什么。

  clr允许将一个对象转换成为它的实际类型或者它的任何基类型。

  使用c#的is和as操作符来转型。

  命名空间用于对相关的类型进行逻辑性分组,开发人员使用命名空间来方便地定位一个类型。

  命名空间和程序集不一定是相关的。特别是同一个命名空间中的各个类型可能是在不同的程序集中实现的。

  一个线程创建时,会分配一个1mb大小的栈。这个栈的空间用于向方法传递实参,并用于方法内部定义的局部变量。栈是从高位内存地址向地位内存地址构建的。

  windows进程启动后,clr加载到其中,托管堆初始化,创建一个线程。当jit将方法的il代码转化成本地cpu指令时,会注意到方法内部引用的所有类型。在这个时候clr要确保定义了这些类型的所有程序集已加载。然后利用程序集的元数据,clr提取与这些类型有关的信息,并创建一些数据结构来标识类型本身。

  堆上的所有对象都包含两个额外的成员类型对象指针和同步块索引。定义一个类型时,可以在类型的内部定义静态数据字段。为这些静态数据字段提供支援的字节是在类型对象自身中分配的。在每个类型对象中,最后都包含一个方法表。在方法表中,类型定义的每个方法都有一个对应的记录项。

  当clr确定方法需要的所有类型对象都已创建,而且方法的代码已经编译之后,就允许线程开始执行方法的本地代码。方法的“序幕”代码执行时必须在线程栈中为局部变量分配内存。

  jit编译器在类型对象的方法表中查找引用了被调用方法的记录项,对方法进行jit编译,再调用jit编译的代码。

  system.object的gettype方法返回的是存储在制定对象的“类型对象指针”成员中的地址。换言之,gettype方法返回的是指向对象类型的一个指针。这样一来就可以判断出系统中任何对象的真实类型。

C#知识点总结系列:5、CLR的组成和运转的更多相关文章

  1. CLR的组成和运转

    CLR的组成和运转 clr基本 CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”.(例如:c#,c++/cli,vb,f#,ironpython,iron ...

  2. MVC之前的那点事儿系列进入CLR

    MVC之前的那点事儿系列(1):进入CLR MVC之前的那点事儿系列,是笔者在2012年初阅读MVC3源码的时候整理的,主要讲述的是从HTTP请求道进入MVCHandler之前的内容,包括了原创,翻译 ...

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

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

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

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

  5. C#知识点总结系列:C# 数据结构

    线性表(Linear List) 线性表是一个线性结构,它是一个含有n≥0个结点的有限序列,对于其中的结点,有且仅有一个开始结点没有前驱但有一个后继结点,有且仅有一个终端结点没有后继但有一个前驱结点, ...

  6. C#知识点总结系列:4、C#中Monitor和Lock以及区别

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...

  7. Android知识点剖析系列:深入了解layout_weight属性

    摘录自:http://www.cnblogs.com/net168/p/4227144.html 前言 Android中layout_weight这个属性对于经常捣鼓UI的我们来说,肯定不会陌生.但是 ...

  8. C#知识点总结系列:3、C#中Delegate和Event

    一.Delegate委托可以理解为一个方法签名. 可以将方法作为另外一个方法的参数带入其中进行运算.在C#中我们有三种方式去创建委托,分别如下: public delegate void Print( ...

  9. C#知识点总结系列:3、C#中Delegate和Event以及它们的区别

    1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁 ...

随机推荐

  1. (转载)(收藏)Awk学习详细文档

    awk命令 本文索引 [隐藏] awk命令格式和选项 awk模式和操作 模式 操作 awk脚本基本结构 awk的工作原理 awk内置变量(预定义变量) 将外部变量值传递给awk awk运算与判断 算术 ...

  2. app慢的可能情况需要优化

    网络请求超时的机制设置,发现如果设置3S太短,导致有一些服务不能成功请求到数据,每次都报超时.问题解决 1. 调大超时时间 2. 优化查询mysql http://blog.chinaunix.net ...

  3. [Android Tips] 22. Available Java 7 Features in Android

    This only allows Java 7 language features, and you can hardly benefit from anything since a half of ...

  4. MVC中权限管理

    权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少.权限管理几乎出现在任何系统里面,只要有用户和密码的系统.权限管理还是比较复杂的,有的固定到某个模 ...

  5. Shopex4.85商派2014年商业模板和商业插件共600多套仅售600元送分销王2代SEO排名神具。

    这批shopex商业插 件+模板都是本人从官方模板网站收购.高价.交换.以及收藏得来.本人因现实工作太忙不得不转手出售这批源代码,限时低价出售给和我一样从事shopex 系统网店电子商务的兄弟姐妹们, ...

  6. OC的总结 ***希望对大家有帮助*** ---高小杰

    1.  NSLog           是Foundation提供的一个输出函数,它的功能非常强大,不仅可以输出字符串,还可以输出各种对象,到后面程序还会见到大量的使用NSLog()函数. 2.  N ...

  7. 约在CBD,吃饭

    午饭当然是外卖. CBD上班的同仁们不用约,都去了一间叫“大食堂”的餐厅. 它在商业街繁华地段的二楼,有1000平米.你不知道么,餐馆们都躲到找不着的角落,变成了厨房,这里的租金便宜得很.但它不做饭, ...

  8. CentOS7安装ftp服务器

    一.问题的提出 想在windows环境下远程连接CentOS的文件并编辑 二.问题的解决 # 安装vsftp服务[root@localhost ~]# yum -y install ftp vsftp ...

  9. Oracle经典SQL

    最近本人整理了一些Oracle sql,现分享给大家,后续还会更新.如果有错误的地方,请指正,共同学习.贴上去的sql都是我测试过的,大家可以粘贴在自己的电脑上试试. 1.查询部门的名称,及最低收入雇 ...

  10. JAG Summer 2012 Day 4 C Connect

    状压dp,由于枚举两维状态会GG,所以只枚举当前位置前m个的状态,就是这个样子大概= =: 呆马: #include <iostream> #include <cstdio> ...