先科普一下,.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. 在Eclipse中使用Maven插件 博客分类: Java相关技术

    简介 本文介绍如何在Eclipse中通过maven插件编写java项目和web项目. 安装Maven 下载Maven最新版本,见:maven.apache.org/download.html 当前版本 ...

  2. codeforce 621B Wet Shark and Bishops

    对角线 x1+y1=x2+y2 或者x1-y1=x2-y2 #include<iostream> #include<string> #include<algorithm& ...

  3. Docker系列(五)OVS+Docker网络打通示例

    环境说明 两个虚拟机 操作系统Centos7 DOcker版本1.8 脚本内容: 1  4  7  10  19  27  32    33  39   -j ACCEPT 47    48  # R ...

  4. Storm系列(十六)架构分析之Executor-Bolt

    准备消息循环的数据 函数原型: 1  let[executor-sampler (mk-stats-sampler (:storm-conf executor-data))] 主要功能: 定义tupl ...

  5. poj1149--PIGS(最大流)

    题意: 有m个猪圈 每个猪圈有不同数量的猪 [0, 1000]有n个顾客 每个顾客需要Bi头猪 有Ai个钥匙 能打开Ai个不同的猪圈顾客按顺序来买猪 只能买他有钥匙的猪 买完之后 这几个猪圈的猪可以相 ...

  6. Learning JavaScript Design Patterns The Module Pattern

    The Module Pattern Modules Modules are an integral piece of any robust application's architecture an ...

  7. 前景还是“钱景”——MM应用引擎的自我博弈

    纵观当前的移动互联网发展态势,巨大的商机已经展露无遗,各个领域的企业及个人对于APP的开发如火如荼,许多APP从诞生伊始,就面临着软件开发的专业性,商业模式的模糊性,以及市场推广的艰巨性三个巨大难题, ...

  8. Spring源码入门——DefaultBeanNameGenerator解析

    我们知道在spring中每个bean都要有一个id或者name标示每个唯一的bean,在xml中定义一个bean可以指定其id和name值,但那些没有指定的,或者注解的spring的beanname怎 ...

  9. Eclipse选择rt.jar的源代码的位置

    1.点 “window”-> "Preferences" -> "Java" -> "Installed JRES" 2. ...

  10. Spring mvc Interceptor 解决Session超时配置流程

    最近公司内部框架中对Session超时这一功能未实现,由于采用iframe结构,Session超时后,当点击左侧系统菜单时,会在iframe的右侧再次弹出登陆框. 该问题是由于没有设置拦截器造成. 添 ...