c# 应用程序运行环境

c2606050113 2012-07-17 10:00:36
很多人只知道c# 应用程序运行 必须有CLR(公共语言运行时)和.net框架的支持,但不知道为啥需要?

其实很简单,因为.exe只是IL指令,CIL(公共中间语言),目前的CPU还不能直接执行IL指令,但将来的CPU也许会具有这种能力。执行exe它的IL代码还必须首先被转换成为本地CPU指令,这属于CLR中即时编译器的工作。总所周知,程序入口点是Main函数,在程序执行之前,CLR检测Main中代码所引用到的所有类型,分配多个内部的数据结构,一个类对应一个数据结构,类中每个方法都会有一个对应的条目,每个条目保存有一个方法实现代码的地址。

当Main函数第一次调用程序中的某个方法时,JITCompiler函数将被调用,也就是将该方法的IL代码编译成本地的CPU指令,注意这是即时编译的,这些本地CPU指令将被保存在一个动态分配的内存块中,然后JITCompiler将前面内部数据结构中被调用方法的地址替换为包含本地CPU指令的内存块地址。最后JITCompiler将跳转到该内存块的代码上。这就是即时编译所做的工作,当该方法执行完毕,它将返回到Main函数中,继续执行下面的代码。

Main函数第二次调用程序的某个方法时,该方法的IL已经被编译成CPU指令,所以这一次执行将直接调用内存块中已有的本地代码,也正因为如此,一个方法只有在首次调用时才会产生一些性能上的损失。但所有对该方法的后续调用都将以本地代码全速执行。

JIT编译器将本地代码存储于动态内存之中,这就意味着关闭程序时,编译生成的本地代码将会被丢弃。再次运行程序依旧要把IL代码转换为CPU指令,这就是为什么每次运行都需要CLR及.net框架支持的原因。
...全文
560 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_24947421 2014-12-30
  • 打赏
  • 举报
回复
码农们问题来了,输出是什么? def is_cool(name): return (name = "I") def person (name): if is_cool (name): print name, "am cool." else: print name,"are not cool." person ("I") person ("YOU")
c2606050113 2012-07-19
  • 打赏
  • 举报
回复
测试给分
Conmajia 2012-07-18
  • 打赏
  • 举报
回复
你可以用NGen.exe。。。

全速运行是Jeffrey吹的。。他书里说「(第二次之后)execute at the full speed of the native code...」

理想很丰满,现实很骨感。。

谁来做个对比测试啊?
c2606050113 2012-07-18
  • 打赏
  • 举报
回复
方法的第二次调用就是调用的本地代码块,我也并没有说第二次调用会弥补什么,只是很多人担心第一次调用会影响性能,其实那个时间是可以忽略不计的。

[Quote=引用 8 楼 的回复:]
.NET是规范,而不是运行效率,不管它怎么说自己的效率好,都没有本地代码快,这是事实,而不是你所解释的“第二次调用”就可以弥补的。本地方法的第一次调用都比.NET的第二次调用快得多。

.NET的优点不是那个,而是规范化,有了一个规范,就可以封装很多底层实现供二次调用,虽然牺牲了性能,但编程速度大大提高了,从第三方控件的使用难度上就看得出,显然.NET的控件调用非常简单,而C++的无论是配置还……
[/Quote]
hjd2357 2012-07-18
  • 打赏
  • 举报
回复
终于明白了
qldsrx 2012-07-18
  • 打赏
  • 举报
回复
.NET是规范,而不是运行效率,不管它怎么说自己的效率好,都没有本地代码快,这是事实,而不是你所解释的“第二次调用”就可以弥补的。本地方法的第一次调用都比.NET的第二次调用快得多。

.NET的优点不是那个,而是规范化,有了一个规范,就可以封装很多底层实现供二次调用,虽然牺牲了性能,但编程速度大大提高了,从第三方控件的使用难度上就看得出,显然.NET的控件调用非常简单,而C++的无论是配置还是使用,都非常麻烦,所以很多方法在C++里没有提供,到了.NET里却有了封装。

不过.NET最大的问题还没法解决,那就是内存管理。虽然微软总说他的自动管理内存多么高级先进,但是他将手动管理托管内存的功能直接去掉是不合理的,导致.NET内存不能及时回收,.NET程序占内存庞大。即使你可以调用GC.Collect来回收内存,但那个最多只能精确到代的回收,而不能对某个对象的内存进行回收,如果要只回收某个临时大对象的内存将无能为力,而重利用内存的控制也非常难实现,而这个在C++中却是非常的容易。
全栈极简 2012-07-18
  • 打赏
  • 举报
回复
你懂的。
yanele 2012-07-18
  • 打赏
  • 举报
回复
了解了.
c2606050113 2012-07-18
  • 打赏
  • 举报
回复
好吧,大牛全当温故了,新手可以看看
c2606050113 2012-07-18
  • 打赏
  • 举报
回复
你来测测呗
熙风 2012-07-17
  • 打赏
  • 举报
回复
了解
c2606050113 2012-07-17
  • 打赏
  • 举报
回复
了解托管程序是如何执行的还是有好处的

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧