一、大家都知道.net的软第一次运行会慢点,以后就快了,这个第一次是指什么?比如,我打开一个A软件,第一次运行会慢点,然后就快了,我再关掉,再打开,还是会慢吗?也就是C#每次打开运行都要即时编译,还是第一次运行编译后一直驻留在本地映像中,以后再打开就从本地映像中读
二,即然第一次运行时编译成本地代码了,为什么在运行时,仍需要程序中dll文件支持(比如,打开软件后,编译完成后,我删掉一个dll文件,程序就没法运行了)
三。C#编译经历了几个阶段,是由IL文件直接编译成本地机器码,还是要经历编译成C,汇编等过程

解决方案 »

  1.   

    1、.net framework是在第一次运行时加载的
      

  2.   


    首先在发布之前编译成IL,也就是我们看到的Assembly(DLL,exe)
    运行的时候由.net framework 的JIT(Just in Time)编译器编译成本机代码运行~~
    这样才能做到.net的跨语言甚至跨平台~
      

  3.   

    首先C#等语言编译成中间代码MSIL,程序执行时才用JIT编译成本机代码.而程序集(DLL)包含MSIL和元数据等,需要的时候才编译成本机代码,但本机代码当然不会永久性存在内存中啦,以我理解,程序结束,本机代码也消失了,你删了DLL当然下次就不行啦。
      

  4.   


    我没有关掉,而是在运行时,即然已编译成本机码驻留在要地映像中,为什么仍需要软件自身的dll支持
      

  5.   

    我来说一下:
    一:运行后在启动,肯定还是一样需要编译的,我们常常说的运行一次后就快了,通常指的是程序在调用某个函数的时候,如果发现没有编译过会进行一次编译,系统会分配一块内存来保存编译后的本机代码,等下次再次调用该函数是就会直接执行内存中的本机代码。
    二:程序在执行前,CLR会检测当前模块应用的所有类型,CLR会分配一个内部数据结构,用以管理对被应用的类型的访问,而且通常并不是一次性将整个dll全部编译成本机代码,知识在调用到某个dll的某个函数的时候,会将该函数的IL执行编译成本机执行,因此不能删除dll
    三:从上面两点可以看出,C#编译是将IL指令直接编译成本机CPU执行的
      

  6.   

    LZ可能是误会编译成本机代码是永久性的,事实很不合逻辑啊,本机代码能放到哪里啊,当然只能是程序运行时才存在了。NET程序必需CLR支持,在其托管功能下运行,与操作系统的底层交互由CLR完成,所以只要机器存在CLR,程序就可以不管目标机器的环境了,这样才实现跨平台跨语言,平台当然都是MS平台,所以本质上不存在包含本机代码的文件。
      

  7.   

    不好意思,看了一下,有很多错别字,在此更正一下
    我来说一下: 
    一:运行后再启动,肯定还是一样需要编译的,我们常常说的运行一次后就快了,通常指的是程序在调用某个函数的时候,如果发现没有编译过会进行一次编译,系统会分配一块内存来保存编译后的本机代码,等下次再次调用该函数时就会直接执行内存中的本机代码。 
    二:程序在执行前,CLR会检测当前模块引用的所有类型,CLR会分配一个内部数据结构,用以管理对被引用的类型的访问,而且通常并不是一次性将整个dll全部编译成本机指令,只是在调用到某个dll的某个函数的时候,会将该函数的IL指令编译成本机指令,因此不能删除dll 
    三:从上面两点可以看出,C#编译是将IL指令直接编译成本机CPU执行的
      

  8.   


    那就是每次运行都要编译咯。。CLR与底层交互?CLR应该只是负责编译,运行时的一些管理,如内存管理,垃级回收等,而底层交互还是由线程执行编译后的机器码交给CPU去处理吧
      

  9.   

    解释很清楚了
    有句话很有用"MSIL仅在需要时才编译"
      

  10.   

    所谓底层就是内存管理,垃圾回收那些东东,C++等语言就可以进行这些低级操作,C#只能在托管功能下运行,与操作系统交互就由.NET完成啦.当然这是我的理解,也不能肯定对的.
      

  11.   

    我昨天看到有遍文章说,.net编译后的机器码,会保存在本地映像中,我们甚至可以直接运行编译的映像中的文件,这就有一个问题了,编译后的机器码到底在内存中,还是在本地映像呢?
      

  12.   

    先简单说明一下允许原理源代码(cs等文件) 编译为il代码(dll,exe等文件)
    双击exe文件,clr程序自动启动,加载exe文件,并根据引用情况,加载dll文件
    找到主入口main方法,即时将il代码编译为机器代码,执行,根据引用的情况,不断的加载il代码,编译为机器代码,执行,执行完了以后不会把编译好的代码清除出内存,下载直接用。回到你的问题一、大家都知道.net的软第一次运行会慢点,以后就快了,这个第一次是指什么?比如,我打开一个A软件,第一次运行会慢点,然后就快了,我再关掉,再打开,还是会慢吗? 也就是C#每次打开运行都要即时编译,还是第一次运行编译后一直驻留在本地映像中,以后再打开就从本地映像中读 ===
    加载clr,建立程序域,每个程序域里面的代码只编译一次,退出程序域就清空
    一般桌面窗口程序,就一个程序对于一个程序域,程序退出,下次进去就又需要重新编译了
    asp.net就是多个网站共享一个程序域的,这样共享的引用会不因为一个网站退出而重新编译二,即然第一次运行时编译成本地代码了,为什么在运行时,仍需要程序中dll文件支持(比如,打开软件后,编译完成后,我删掉一个dll文件,程序就没法运行了) 编译成本地代码的概念不是说生成了一个文件,只是在内存里编译好了,如果删除dll,那下次如何再次编译?程序还在使用dll也不允许删除呀
    三。C#编译经历了几个阶段,是由IL文件直接编译成本地机器码,还是要经历编译成C,汇编等过程 
    源代码 到 il中间语言,这是可以分发了 在别的机器运行时,才真正编译到机器语言,和传统的编译语言不同。
    编译器从来都不会编译为c,汇编等语言的吧。以前有说c++需要先编译为c,现在不知道,汇编就是机器语言,一一对应。
      

  13.   

    我昨天看到有遍文章说,.net编译后的机器码,会保存在本地映像中,我们甚至可以直接运行编译的映像中的文件,这就有一个问题了,编译后的机器码到底在内存中,还是在本地映像呢?
      

  14.   

    这个看情况.你用ngen生成的本地指令是保存的.否则是在内存中随着进程的结束而消失的.
    而即使是用ngen生成的本地指令,也需要有原dll/exe的存在才能正常运行;原因很简单,ngen只是把
    IL编译成本机码而已.元数据仍然保存在原dll/exe中.
      

  15.   


    不是'会'保存在本地映像中,而是‘可以’,这样编译的话就不是托管代码,根本就不需要.net 框架就可以执行了。微软就提供了这样的工具,但是这样做的话就不能跨平台了。也就是说,通过工具可以将编译后的机器码保存到本地文件中,你发布的时候就发布这些文件就可以了。而IL指令的执行是即时编译的,编译的机器码是在内存中的。其实这没有多大的性能损耗的,用微软的话说,编译的时间肯定没有你在方法内部所花费的时间多。
    托管代码有的时候可能还会优于非托管代码:
    比如如果应用程序在Pentium 4上运行,JIT编译器可以检测到并生成使用Pentium 4 提供的所有特殊指令的本机代码,通常,非托管应用程序是为最低配置的CPU编译的,避免使用在更新CPU上提高应用程序性能的特殊指令
      

  16.   


    对的,是这样的我再问下:
    楼上有位朋友说:“与操作系统的底层交互由CLR完成”
    CLR与底层交互?CLR应该只是负责编译,运行时的一些管理,如内存管理,垃级回收等,而底层交互还是由线程执行编译后的机器码交给CPU去处理吧??