先科普一下,.Net是一个用于Windows的托管代码模型,用于高效构建具有视觉上引人注目的用户体验的应用程序。但这个模型生成的代码并非可执行代码,而是由.Net公共语言运行库环境执行的IL代码。所以,每次执行代码时,都会由.Net将IL代码翻译为机器代码。所以,效率上自然会受到一定影响。对此,微软在.Net中附带一个将IL代码转换为Native代码的工具Ngen.exe。它可以创建一份程序集文件至类似于C:\WINDOWS\assembly\NativeImages_v4.0.30319_32的文件夹内。这个文件夹下通常会包含如下信息:

1.公共语言运行库的版本

2.x64版本或x86版本信息(包括x86,x64和Itaninum)

3.Native代码

如果这样一个Ngen程序集被创建了(暂且这么叫它),那么,CLR载入程序集文件时,就不会实时编译,而会使用Ngen程序集中的代码,于是,应用程序集的启动速度、运行速度都得到了提升。

看起来很美好,是吧(哪种技术听起来不美好…)?既得到了托管代码的所有优点,还得到了近似于普通非托管代码的执行性能我们先来分析一下它的优缺点:

Advantage:1.提高启动速度, 因为代码已经编译成Native代码, 所以在运行时就不需要编译了。

2.减少应用程序的工作集,如果一个程序集会被同时载入到多个进程/Appdomain,,在这个程序集上运行Ngen能减少应用程序的工作集。因为Ngen会将IL编译为Native代码后,保存到单独的文件夹。这个文件夹能在同一时刻对多个进程空间起作用,且允许代码共享。所以, 每个进程/AppDomain不必为自己拷贝一份代码。

Disadvantage:1.编译Native代码后,原IL代码不可删除。因为运行的时候,CLR需要访问程序集的metadata,这需要IL与Native两者。且很多人认为发布Native代码就可以避免IL原始代码泄露,以保护知识产权,其实这是错的。

2.NGen文件可能会过时: 当CLR载入NGen所映射文件时,,它会比较以前编译的代码和当前的执行环境的很多特征, 如果任何特征不匹配,预编译的文件就不能被使用, JIT编译器进程就要使用。下面必须被匹配的部分特征列表:

① 程序集模块的版本ID (MVID)

② 被引用的程序集的版本ID

③ 处理器类型

④ CLR版本

⑤ Build类型(release, debug, optimized debug, profiling, 等等)

若预编译程序集过时,可以以升级的方式运行Ngen.exe来补救, 这告诉工具对以前曾经被执行Ngen操作的所有的程序集上运行Ngen。当终端用户安装.NET Framework的一个新service pack,,那么service pack的安装程序将会在更新模式下自动运行Ngen.exe, 使得NGen文件保持和CLR的版本一致。

4. 较差的载入时性能(重定位/绑定): 程序集文件仍是标准的Windows PE文件, 每个文件包含着一个优先使用的基地址。 CLR会对于内存地址进行计算,导致额外的性能消耗。然而, Ngen程序集文件的一些内存地址引用是静态计算的, 当Windows加载一个Ngen文件时, 它检查文件是否被载入到优先的基地址上, 如果文件没有载入到优先的基地址, Windows会重新定位文件, 修改所有内存地址引用。这是极其耗时的, 因为Windows必须载入整个文件, 并修改文件中的很多字节. 此外, 这个页面文件对应的代码不能跨进程边界共享。

5. 较差的执行时性能: 当编译代码时, Ngen对执行环境做出的假设不会比JIT编译器的多, 这会造成Ngen产生较保守的代码, 例如, Ngen不能优化一些CPU指令。 Ngen到处插入代码来调用类的构造函数, 因为它不知道代码执行的次序, 不知道类的构造函数是否已经被调用了。 一些Ngen应用程序反而会比JIT编译的代码慢大约5%, 因此, 如果你打算使用Ngen来提高应用程序的性能, 你应该对比Ngen和非Ngen版本的应用程序, 确定Ngen版本在实际执行时并不慢。 对于一些应用程序, 减小的工作集大小会提高性能, 因此Ngen总体上还是会取胜。

Ngen的利弊,需要大家自己去权衡,但对于客户端应用程序,Ngen会对于提高启动速度或者减小工作集有帮助。此外,如果Ngen被用于所有的客户端应用程序的程序集, 那么CLR就根本不需要载入JIT编译器, 从而更进一步地降低了工作集. 当然, 如果只有一个程序集不是Ngen所创建或者如果一个程序集的Ngen文件不能被使用, JIT编译器就会被载入, 应用程序的工作集将会增加。

如何使用Ngen呢?很简单我们只需要两个命令就可以玩转它,这两个命令是

Ngen install filepath

Ngen uninstall filepath

当我们想创建一份Ngen程序集时,只要按如下步骤做:假设E盘内有一个WindowsFormsApp.exe文件,它属于WindowsFormsApp工作集。打开命令提示符,输入“cd C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319”(目录因Windows、.Net版本而异),回车。再输入“Ngen install e:\WindowsFormsApp”,回车。这样,一份Ngen工作集就在本地创建完成了。当然想卸载它,只要输入“Ngen uninstall e:\WindowsFormsApp”,回车即可。

当然,这只是本地Ngen工作集,要在客户机上创建,必须要在安装软件中加入Ngen代码。

Ngen生成Native代码实战及优缺点分析的更多相关文章

  1. RocketMQ延迟消息的代码实战及原理分析

    RocketMQ简介 RocketMQ是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的.高可靠.万亿级容量.灵活可伸缩的消息发布与订阅服务. 它前身是MetaQ,是阿里基于Kafka ...

  2. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 “8小时内拼工作,8小时外拼成长 ...

  3. Android Native 代码NDK开发学习笔记

    引用:http://www.kunli.info/2011/08/21/android-native-code-study-note/ JNI,全称Java Native Interface,是用于让 ...

  4. React Native 项目实战-Tamic

    layout: post title: React Native 项目实战 date: 2016-10-18 15:02:29 +0800 comments: true categories: Rea ...

  5. JDK和Cglib实现动态代理实例及优缺点分析

    Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...

  6. Javascript中,实现类与继承的方法和优缺点分析

    Javascript是一种弱类型语言,不存在类的概念,但在js中可以模仿类似于JAVA中的类,实现类与继承 第一种方法:利用Javascript中的原型链 //首先定义一个父类 function An ...

  7. TaintDroid剖析之Native方法级污点跟踪分析

    1.Native方法的污点传播 在前两篇文章中我们详细分析了TaintDroid对DVM栈帧的修改,以及它是如何在修改之后的栈帧中实现DVM变量级污点跟踪的.现在我们继续分析其第二个粒度的污点跟踪—— ...

  8. Scala 深入浅出实战经典 第39讲:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. .net postsharp编译时生成的代码?

    使用PostSharp进行AOP框架设计:一个简单的原型   AOP已经不是一个什么新名词了,在博客园使用关键字搜索可以查出n多条关于AOP的介绍,这里就不再赘述了. 在Bruce Zhang's B ...

随机推荐

  1. Html笔记(二)字体

    字体标签:<font> 例:<font size=5 color=red>字体标签示例</font> 注:简单颜色可以直接写对应的英文,复杂的颜色用16进制表示,表 ...

  2. HDU 1117 免费馅饼 二维动态规划

    思路:a[i][j]表示j秒在i位置的数目,dp[i][j]表示j秒在i位置最大可以收到的数目. 转移方程:d[i][j]=max(dp[i-1][j],dp[i-1][j-1],dp[i-1][j+ ...

  3. jsp网站与discuz论坛用户同步

    需求分析: 要想实现A(jsp网站)和B(discuz论坛)的同步,这里说的同步指的是 在AB网站任意一方注册之后在另一方都可以直接登录 AB两网站之间的用户登陆状态是同步的,在任意一方登录后,另一方 ...

  4. aix 扩展文件系统

    今天发现公司的oracle测试 数据库不能启动,检查警告日志日志,提示归档空间不足,不能归档,于是扩展文件系统: 1.检查rootvg卷组的剩余空间[p2704u]:[/dsg/oracle11]$ ...

  5. SSDT – Error SQL70001 This statement is not recognized in this context-摘自网络

    March 28, 2013 — arcanecode One of the most common errors I get asked about when using SQL Server Da ...

  6. linux进程,作业,守护进程,进程间同步

    ps axj命令查看系统中的进程.参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数x表示不仅列有控制终端的进程,也列出所有无控制终端的进程,参数j表示列出与作业控制相关的信息: 凡是TP ...

  7. light oj 1294 - Positive Negative Sign

    1294 - Positive Negative Sign   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: ...

  8. System Address Map Initialization in x86/x64 Architecture Part 2: PCI Express-Based Systems

      原文  http://resources.infosecinstitute.com/system-address-map-initialization-x86x64-architecture-pa ...

  9. careercup-递归和动态规划 9.3

    9.3 在数组A[0...n-1]中,有所谓的魔术索引,满足条件A[i]=i.给定一个有序整数数组,元素值给不相同,编写一个方法,在数组A中找出一个魔术索引,若存在的话. 进阶: 如果数组元素有重复值 ...

  10. MySQL 数据库常用命令 超级实用版分享

    1.MySQL常用命令 create database name; 创建数据库 use databasename; 选择数据库 drop database name 直接删除数据库,不提醒 show ...