.NET 代码编译过程
作为一种代码指令平台,Microsoft .NET比微软公司先前推出的其他技术平台要来得更为复杂。由于.NET提供了对多种编程语言以及(在理论上说)多重平台的支持,这就需要在传统的两个代 码层添加一个中间代码层。在这里,传统的两层分别是源代码层和编译后的本机代码层。新加的代码层给.NET平台带来了额外的灵活性,不过,反过来却又增加 了系统的复杂性。此外,由于这一新代码层的出现,一连串的新型应用程序部署选项也首次展现在了程序员的面前。
.NET之与众不同:MSIL
在Microsoft .NET框架内,应用程序可以用好多种高级程序语言编写、创建,例如VB.NET、C#乃至COBOL .NET等等都可以编写.NET应用程序。而通过每一种遵守.NET规范的编程语言所编写的程序代码首先都得通过一种初始编译步骤从源代码变成.NET的 公共标准语言:MSIL(微软中介语言:Microsoft Intermediate Language)。MSIL自身是一种完整的、和对象相关的语言,只有它才可能创建出应用程序。为了大致了解MSIL的一些有关情况,你可以参看“通过 MSIL语言了解CLR的运行原理”一文。.NET应用程序是以MSIL的形式出现的,只有在程序执行的时候才通过即时编译器(JIT)被编译为本机代 码。
.NET的编译过程:从源代码到本机指令
只要装载了assembly代码就会进行JIT编译,可见这是一种汇编级的编译(了解更多assembly技术的细节请参看“Assembly—治愈
“DLL地狱”的良方?”一文)。在编译过程中,JIT编译器一旦首次遭遇对象的索引就会装载匹配对象各个方法声明的对应程序。这样,以后调用方法的时候
就会编译其IL,而方法的对应根程序则被方法的编译后代码的地址所取代。这一过程在每次方法被首次调用的时候进行,产生的本机代码则被缓冲以便会话过程中
下次装载assembly代码的时候可以被使用。显然,这样的指令系统相比传统的编译语言需要更大的处理能力,不过其要求也没有你想象的那么高。
在这里必须澄清一个普遍误解的错误概念,那就是不少人认为.NET应用程序是解释型而非编译型的程序。另外,还有这样的常见错误认识:JIT编译的代码存
储在磁盘上并且可以为同一应用程序执行。虽然这样做也不是不可以,但是,你很快就会明白,这可不是缺省的编译方案。应用程序的IL代码实际上在每次应用程
序运行的时候都会被重新编译为本机代码。
两种编译器
事实上,JIT编译器分成两种(经济编译器和普通编译器),而且它们生来也不是平等的。经济JIT编译器代表了运行一个.NET应用程序所需要的最少功
能,它直接用对等的本机代码取代每一条MSIL指令,不进行任何优化从而也带来更少的系统负载。这也意味着它主要应用在内存等资源比较紧张的平台上。
另一方面,普通JIT编译器则是缺省的运行时配置,它会对其产生的代码进行即时优化。这样做无形中给予了.NET超出传统预编译语言的一个优点:预编译语
言只能对其处理的代码将要运行于其上的平台做一番大致的事前估计。JIT编译器可以经过准确调节达到当前运行时状态,结果可以完成一些预编译语言无法完成
的工作:
·更高效地利用和分配CPU寄存器
·在适当的情况下实施低级代码优化,比如常量重叠、拷贝复制、取消范围检查、取消常规副表达式以及方法内联等
·在代码执行期间监控当前的物理和虚拟内存需求从而更高效地利用内存
·产生特定的平台指令以准确、充分地利用实际的处理器模式
.NET编译的结果就是JIT所带来的额外负载要求并没有产生显著的性能损失。
性能选项
这就是说,每次运行应用程序时MSIL就会被JIT编译。记住,这就是常识了,然后,根据以上内容中说明的原理,在开始启动应用程序以及首次使用非核心功能的时候显然会导致低于优化级的系统性能表现。那么你又该采取什么措施把这种负面影响降低到最小呢?
微软公司的对策是为我们提供了一种名为Pre-JIT的编译器(也被称做本机映像生成器:Native Image
Generator,程序名因此是Ngen.exe)。从表面上看,至少它也算是应付任何性能问题的一项治疗手段。Pre-JIT编译器在运行时之前被调
用,在安装时,它会把全部assembly形式的MSIL编译为本机代码。这种本机代码随后存储在全局assembly缓存(Global
Assembly Cache)的某一个特殊部分供以后使用,这样就完全绕过了JIT编译过程。
乍看之下,这样做应该是解决先前的问题了,对客户端代码而言尤其如此。但是,你还记得吗?普通JIT在编译MSIL的时候实施了大量的即时优化操作。而许
多此类的优化操作,尤其是那些牵扯到寄存器和存储器使用的优化,都是由系统的当前需求所驱动的。所以,批量编译assembly代码的举措就会阻止这些优
化的进行从而在实际上产生出运行更慢的最终代码。在你采用这个法子之前,微软的建议是,比照普通编译下的当前条件,把你的JIT和Ngen版本设置为目标
平台上的同一汇编级。
.NET 代码编译过程的更多相关文章
- 【转】Java代码编译过程简述
转载:https://blog.csdn.net/fuzhongmin05/article/details/54880257. 代码编译是由Javac编译器来完成,流程如下图1所示: 图1 Javac ...
- java代码编译过程
简单随笔 java程序需要先编译成class文件然后才能执行,由于是编程成立机器代码,虚拟机加载内存的时候更快的执行. java文件编译成class文件步骤如下: 1)词法分析,检查每一个关键字单词是 ...
- ios oc 代码 转换为 c++ 描述代码编译过程
clang -rewrite-objc main.m #import <Foundation/Foundation.h> #import <objc/runtime.h> // ...
- python代码是解释型语言,为什么还有编译过程?
Python 代码在运行前,会先编译(翻译)成中间代码,每个 .py 文件将被换转成 .pyc 文件,.pyc 就是一种字节码文件,它是与平台无关的中间代码,不管你放在 Windows 还是 Linu ...
- 【lombok】使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法
错误如题:使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法 报错如下: 解决方法: 1.首先查看你的lombok插件是否下载安 ...
- C语言代码区错误以及编译过程
C语言代码区错误 欲想了解C语言代码段会有如何错误,我们必须首先了解编译器是如何把C语言文本信息编译成为可以执行的机器码的. 背景介绍 测试使用的C语言代码 导入标准库,定义宏变量,定义结构体,重命名 ...
- GCC编译过程
以下是C程序一般的编译过程: gcc的编译流程分为四个步骤,分别为:· 预处理(Pre-Processing) 对C语言进行预处理,生成*.i文件.· 编译(Compiling) 将上一步生成的*.i ...
- Linux系统GCC常用命令和GCC编译过程描述
前言: GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言.GCC 很快地扩展,变得可处理 C++.后来又 扩展能够支持更多编程语言,如Fortran. ...
- 如何提升代码编译的速度 iOS
前阵子有遇到代码编译速度慢的问题,特别是在swift和object-c混编的过程中问题很突显. 网上找到一篇蛮好的文章里面又一些解决方法 推荐一下 http://www.open-open.com/l ...
随机推荐
- SpringMvc之handler深入AbstractControllerhe和MultiActionController和内部资源视图解析器
AbstractControllerhe 若处理器继承自AbstractController类,那么该控制器就具有了一些新功能.因为AbstractController类还继承自一个父类WebCont ...
- javascript 数组操作 转
javascript之数组操作 1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一 ...
- backbonejs中的集合篇(一)
一:集合概念 集合是多个模型,如果把模型model理解为表结构中的行,那么集合collection就是一张表,由多个行组成.我们经常需要用集合来组织和管理多个模型. 二:创建集合 1:扩展Backbo ...
- iframe-摘自网友
定义和用法 iframe 元素会创建包含另外一个文档的内联框架(即行内框架). HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict ...
- LSM树——放弃读能力换取写能力,将多次修改放在内存中形成有序树再统一写入磁盘
LSM树(Log-Structured Merge Tree)存储引擎 代表数据库:nessDB.leveldb.hbase等 核心思想的核心就是放弃部分读能力,换取写入的最大化能力.LSM Tree ...
- HTTP方法简介
GET 请求获取资源 HEAD 与GET类似,但服务器只返回首部 PUT 与GET相反,向服务器写入文档 POST 向服务器输入数据,通常使用HTML表单形式 TRACE 客户端发起请求时,需要穿越防 ...
- 重点关注之自定义序列化方式(Protobuf和Msgpack)
除了默认的JSON和XML序列化器外,如果想使用其它格式的(比如二进制)序列化器,也是可以的.比如著名的Protobuf和Msgpack,它们都是二进制的序列化器,特点是速度快,体积小.使用方法如下. ...
- php解密java的DES加密
echo openssl_decrypt( $密文 ,"des-ecb" , $密钥 );
- angular-xeditable
http://vitalets.github.io/angular-xeditable/#text-simple ng-repeat="user in users" e-rows= ...
- CIO谈:基于K2 BPM平台怎么做报销?
即时!可视!可控!高效! 面对报销系统四大业务目标,有一个对策——用K2! 演讲人:沈明 大鹏天然气CIO 查看完章分享内容请关注K2官方微信