谈谈JIT编译器和本机影像生成器(NGen.exe)
前言
在看《CLR》的时候,作者在开篇的时候提到了NGen.exe,前面一节执行程序集的代码中提到:程序或方法执行前会执行MSCorEE.dll中的JIT函数把要执行方法的IL转换成本地的CPU指令,讲代码放在内存块中,第二次调用方法的时候,由于已对方法进行了验证和编译,所以会直接执行内存块中的代码,不需要再执行JIT函数编译了。因为在方法没调用之前都会要调用JIT函数编译,在这一节的最后作者也提到,通过实验表明,CLR的JIT编译器似乎没有使自己的应用程序达到应有的性能,然后就提到了.Net Framework SDK提供的NGen.exe工具。
疑问
当时看到这段话的时候很兴奋,然后就接着看作者写的NGen.exe的介绍,可惜作者只用了几页的篇幅讲了下,感觉太少了,也有些疑问,然后就在MSDN上搜,找到了《Ngen.exe(本机映像生成器)》,仔细看了下,和作者写的差不多,其中详细写了NGen.exe的用法,自己也照着上面的方法,自己敲了个遍,可能是官方写的太官方或是小弟理解能力有限,总有点云里雾里的,然后又在博客园找到了一位园友写的《本机影像生成器(Ngen.exe)工具使用实践》,仔细看了下,主要是NGen.exe项目的简单应用,不是很全面的介绍NGen.exe的用法。
结合上面所接触的,有几个疑问:
1,JIT编译器的执行条件
上面那位博文的作者在文章中提到
但是《CLR》这本书的作者在写执行程序集中的代码这一节中提到:JIT编译器将本地CPU指令存储到动态内存中。一旦应用程序终止,编译好的代码也会被丢弃。所以再次运行应用程序,JIT编译器必须再次将IL代码编译成本地指令。
就是说程序终止,再次运行程序还是会执行JIT编译器的。但是与上面“实时编译只在程序第一次运行时编译”有点矛盾。
2,NGen.exe的作用
MSDN和《CLR》的作者都说了NGen.exe的作用有两点,改善内存使用情况和更快的应用程序启动速度,这里我只说使应用程序启动速度加快。
NGen.exe操作会把相应的程序集的IL代码编译成本地代码,放到磁盘的某一目录下,下次执行程序的时候CLR会检测是否存在对应程序集由NGen.exe生成的文件,若不存在执行JIT编译器编译,若存在跳过JIT编译器,JIT编译器执行的条件是在执行方法之前编译,这时候我就有点迷糊了,MSDN上写的是NGen.exe的作用是使应用程序启动的速度加快而不是程序运行的速度加快,就是说在程序运行的时候,如果调用某一方法,还是会执行JIT编译器的,就有点矛盾了。或者这样说JIT编译器是不是在程序启动的时候执行,执行所有代码的编译?如果是,那NGen.exe使程序启动的速度加快这个作用是对的,我个人感觉并不是这样,比较那么纳闷的是为什么没有使程序运行的速度加快,因为NGen.exe已经把相关的程序集编译好了,程序调用某一方法的时候就不需要再执行JIT编译器了,少了编译速度不是更快了?
3,NGen.exe安装程序集依赖项
MSDN中提到

但是我试了下并没有安装程序的依赖项
4,NGen.exe检测映像变化
或者不是NGen.exe检测,其他的方式暂时也没发现,如果是自己程序中的程序集发生变化可以通过程序来判断,但是外部的变化就不太好检测了,比如:
5,NGen.exe更新映像
MSDN提供了两种更新映像的方式,但是没有指定程序集更新,如果说程序集发生变化,就需要全部更新映像花费时间太长,下面的更新方式的说明不是很清楚,不知是不是自动检测映像变化更新。
后记
以上疑问,跪求大神指点。。。。
不知是用NGen.exe后会性能会优化多少,暂时没有找到相关的方法测试,有机会会好好测试下,想想NGen.exe的用武之地应该是大型的Winfrom项目,而且业务逻辑应该很复杂的那种,如果只是简单的程序,就没这个必要了。
谈谈JIT编译器和本机影像生成器(NGen.exe)的更多相关文章
- 五、CLR加载程序集代码时,JIT编译器对性能的产生的影响
1.CLR首次加载代码造成的性能损失 四.CLR执行程序集中代码介绍了CLR在首次执行一个类的时,会初始化一个内部结构,然后当目标方法被首次调用时,JITComplier函数(JIT编译器)会验证IL ...
- Ngen.exe和本机映像缓存
本机映像生成器创建托管程序集的本机映像,并且将该映像安装到本地计算机的本机映像缓存中.本机映像缓存是全局程序集缓存的保留区域.一旦您为某个程序集创建了本机映像,运行库在每次运行该程序集时就会自动使用该 ...
- 浅谈对JIT编译器的理解。
1. 什么是Just In Time编译器? Hot Spot 编译 当 JVM 执行代码时,它并不立即开始编译代码.这主要有两个原因: 首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编 ...
- NET基础课--JIT编译器如何工作1
1..Net运行时调用JIT编译器,用来把由C#编译器生成的IL指令编译成机器代码.这一任务在应用程序的运行期间是分步进行的.JIT并不是在程序一开始就编译整个应用程序,取而代之的是,CLR是一个函数 ...
- JIT编译器技术理解
参考链接: https://blog.csdn.net/liaodehong/article/details/51605457 https://www.cnblogs.com/insistence/p ...
- 深入浅出 JIT 编译器
转载 https://www.ibm.com/developerworks/cn/java/j-lo-just-in-time/ JIT 编译器在运行程序时有两种编译模式可以选择,并且其会在运行时决定 ...
- JIT编译器
深入理解Java Class文件格式(九) http://blog.csdn.net/zhangjg_blog/article/details/22432599 http://blog.csdn.ne ...
- 《Java性能权威指南》笔记----JIT编译器
概览 编译型语言(C++,Fortran等):运行程序前,需要用编译器将代码静态编译成CPU可执行的汇编码.汇编码针对特定的CPU. 优点:只需编译一次,且有足够的程序信息来优化汇编码.执行速度快: ...
- Java虚拟机解释器与JIT编译器
一.JAVA编译相关概念 1.动态编译(dynamic compilation)指的是“在运行时进行编译”:与之相对的是事前编译(ahead-of-time compilation,简称AOT),也叫 ...
随机推荐
- 猥琐的wordpress后门分享
https://www.t00ls.net/thread-37312-1-1.html 一个可以自动调用管理员帐号登录wordpress后台的方法. <?php require('../../. ...
- 浅析PHP中for与foreach两个循环结构遍历数组的区别
遍历一个数组是编程中最常见不过的了,这里跟大家讨论下for和foreach两种方法.用这两种方法执行遍历的场景太多太多了,这里我们只针对以下两个数组作为例子来讨论.所谓管中窥豹,多少能理清一点两者的区 ...
- Nginx 配置从零开始
作为一个 nginx 的初学者记录一下从零起步的点滴. 基本概念 Nginx 最常的用途是提供反向代理服务,那么什么反向代理呢?正向代理相信很多大陆同胞都在这片神奇的土地上用过了,原理大致如下图: 代 ...
- JQuery之$.ajaxPOST数据
function postSimpleData() { $.ajax({ type: "POST", url: "/Service/SimpleData", c ...
- Zend Studio XDebug调试配置
最近在配置zend studio时找了些资料,发现了这个,说的比较详细 搭建Zend Studio 10.5 和XDebug 环境,试图进行 Drupal的调试, 经历了一些困难,但是最终解决了问题, ...
- 通过js实现回到顶部功能
许多商城网址,当我们滚动到一定高度时,我们会发现一般会出现一个回到顶部的js选项,点击轻松实现回到顶部,交互效果会显得比较人性化,且回到顶部过程中若在滚动滚动条时可以停止滚动,现在让我们来实现吧 我总 ...
- GitLab版本管理
GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的功能,能够浏览 ...
- [PDO绑定参数]使用PHP的PDO扩展进行批量更新操作
最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用了PDO做参数绑定,其中遇到了一个坑. 方案选择 笔者已知的做批量更新有以下几种方案: 1.逐条更新 这种是最简单的方案,但无疑也 ...
- Nodejs之MEAN栈开发(三)---- 使用Mongoose创建模型及API
继续开扒我们的MEAN栈开发之路,前面两节我们学习了Express.Jade引擎并创建了几个静态页面,最后通过Heroku部署了应用. Nodejs之MEAN栈开发(一)---- 路由与控制器 Nod ...
- C#编程模式之扩展命令
C#编程模式之扩展命令 前言 根据上一篇的命令模式和在工作中遇到的一些实际情况,有了本篇文章,时时都是学习的一个过程,会在这个过程中发现许多好的模式或者是一种开发方式,今天写出来的就是我工作中常用到的 ...