精灵巫婆 发表于 2015-1-18 11:21:54

ASP.NET网页设计[你必需晓得的.NET]第二十六回:熟悉元数据和IL(下)仓酷云

C#中有两处地方用到new关键字,第一处也是最常见的一处是用在调用构造函数的时候,这种情况也是大家见的最多的一种。另一处是用在派生类中,作用有隐藏成员,切断继承关系等,相信第二处的用法大家明显要比第一处生疏。系列文章目次索引:《你必需晓得的.NET》

<br>说在,开篇之前书接上回:
第二十四回:熟悉元数据和IL(上),第二十五回:熟悉元数据和IL(中)

我们持续。

终究到了,说说元数据和IL在JIT编译时的脚色了,固然两个回合的展垫不免浪费,可是却涓滴不为过,由于只要充实的认知才有充足的体味,手艺也是云云。那末,我们就入手下手沿着办法挪用的轨迹,跟随元数据和IL在谁人奥秘刹时所奉献的力气吧。5元数据和IL在JIT编译时
CLR终极实行的只要当地呆板码,以是JIT编译的感化是在运转时将IL代码剖析为呆板码实行。关于JIT编译,我们会以专门的篇幅来周全懂得,本文只将眼光存眷于元数据和IL在程序实行时的感化和介入细节。起首,IL是基于栈实行的,实行办法挪用时,办法参数、部分变量另有前往值等被分派于栈上,并实行其挪用历程,既然是存眷JIT编译时,因而我们天然而然将存眷办法的实行,由于JIT编译是以实行办法挪用而触发的。
起首,对本文入手下手的代码加点新料:
//Release:code04,2009/02/24//Author:Anytao,http://www.anytao.com//List:Base.cspublicclassBase{publicvoidM(){Console.WriteLine("MinBase");}publicvirtualvoidN(){Console.WriteLine("NinBase");}}另有:
//Release:code05,2009/02/24//Author:Anytao,http://www.anytao.com//List:Three.cspublicclassThree:Base{privatestaticintID{get;set;}publicoverridevoidN(){//SomethingnewinThreeConsole.WriteLine("NinThree");}publicvoidM(){Console.WriteLine("MinThree");M1();}publicvoidM1(){Console.WriteLine("M1inThree");}}另有实行代码:
staticvoidMain(string[]args){Basethree=newThree();three.M();three.N();}小窥办法表
以该例而言,实行Main办法挪用时,同时陪伴着关于Three实例的创立,和响应范例信息的加载。我们先将范例信息创立的奥密放在今后的内容中,好留点牵挂在将来发扬,哈哈。但是,范例加载必定是在实例创立之前完成的,也就是我们经常提起的办法表创立。范例加载是由classloader卖力实行的,其历程简言之就是从元数据表中猎取响应的范例信息,创立办法表(包括CORINFO_CLASS_STRUCT布局),其布局次要包含非虚办法表和虚办法表,依照承继的虚办法、新引进的虚办法、实例办法和静态办法的按次分列,以类Three范例为例其CORINFO_CLASS_STRUCT布局能够暗示为:

<br>
Note:在本例中Three没有界说任何静态办法,其办法表中父类办法N已有子类覆写,同时由于有静态成员存在的缘故原由,CLR会主动创立范例机关器,具体情形可参考《你必需晓得的.NET》1.2节“甚么是承继”。
我们能够同过加载SOS调试来懂得响应的办法表信息:


[*]在three.N()挪用处打好断点,来检察该时候的dump信息,就像一个内存快照,发明几工具就看拍照师的水准。
[*]然后,经由过程dumpheap加载范例信息,猎取办法表地点(0x002a354c),
!dumpheap-typeThreeAddressMTSize01d332c4002a354c12total1objectsStatistics:MTCountTotalSizeClassName002a354c112Anytao.Insidenet.MetadataIL.Three

[*]并依据MT地点,以dumpmt检察相干的MethodDesc信息,
!dumpmt-md002a354cEEClass:002a15b4Module:002a2f2cName:Anytao.Insidenet.MetadataIL.ThreemdToken:02000003(E:anytaoTodayOnWritingMetadataILAnytao.Insidenet.MetadataILAnytao.Insidenet.MetadataILinDebugAnytao.Insidenet.MetadataIL.exe)BaseSize:0xcComponentSize:0x0NumberofIFacesinIFaceMap:0SlotsinVTable:10--------------------------------------MethodDescTableEntryMethodDescJITName6f756a706f5d1328PreJITSystem.Object.ToString()6f756a906f5d1330PreJITSystem.Object.Equals(System.Object)6f756b006f5d1360PreJITSystem.Object.GetHashCode()6f7c74606f5d1384PreJITSystem.Object.Finalize()002ac0b8002a3514NONEAnytao.Insidenet.MetadataIL.Three.N()002ac0d0002a3540JITAnytao.Insidenet.MetadataIL.Three..ctor()002ac0a8002a34f4NONEAnytao.Insidenet.MetadataIL.Three.get_ID()002ac0b0002a3504NONEAnytao.Insidenet.MetadataIL.Three.set_ID(Int32)002ac0c0002a3520NONEAnytao.Insidenet.MetadataIL.Three.M()002ac0c8002a3530NONEAnytao.Insidenet.MetadataIL.Three.M1()经由复杂的Dump,办法表的信息和我们图示的信息相差无几,仔细的不雅众大概会发明Dump信息中其实不包括Three::cctor(),那末你答对了。图示的cctor是我基于为Three完成了范例机关器(静态机关函数)而出格到场的,而代码中dump的办法表并没有把范例机关器包括在内,这是个小大意,但愿仔细的您看得够透。
实行细则
详细的实行历程为为:


[*]classloader从TypeDef元数据表加载相干元数据信息,包含以后范例,承继条理的一切父类和完成的接口元数据,依据这些信息创建CORINFO_CLASS_STRUCT布局:

<br>
固然,对classloader,我们能够举行一点常识济急:

<br>上课啦:classloaderClassicLoader是CLR供应的基础组件之一,感化正像其称号所宣传的那样,load一个Class给CLR,classloader将Metadata和IL从PE文件中掏出,并加载到运转时内存,复杂的说就是我们上面要先容的全历程缩影。
固然,假如你老是对CLR的ClassicLoader铭心镂骨,不克不及豁然。那末,我们也能够参考MSDN的材料来完成自界说的ClassicLoader,但愿个中能供应灵光一现的思索。
anytao.com


[*]加载以后,办法实行之前的CORINFO_CLASS_STRUCT中一切的办法表槽都保留了办法应当实行的举动逻辑,这些信息保留在被称为办法形貌(MethodsDesc)的布局中,而MethodDesc则被初始化为指向IL代码,同时还包括一个指向触发JIT编译的PreJitStub地点,以下:

<br>
上述一切办法形貌都指向各自的IL代码地点和JIT编译器,在此我们仅仅以N()办法为例来举行申明,具体的情形能够参考MSDN相干内容。


[*]复杂的说,任何办法第一次实行时城市起首触发实行JIT编译,JIT的次要事情就是将IL代码翻译为NativeCode,并拔出指向NativeCode的jmp指令地点掩盖本来的CallJITCompiler指令:

<br>


[*]当该办法再次被实行时,由于MethodDesc中保留了呆板码地点,今后的实行将不会实行JIT编译历程而间接实行x86(X64)呆板码,完成全部实行历程。
纵不雅全部JIT编译的全历程,其细节的完成远比我们这里出现的庞大,在大略的步骤中我们大抵懂得了元数据和IL在全部过程当中的感化、脚色和干系,对懂得CLR运转机制而言,得当的选择是明智的,假如有更多的心机探究,那末就在今后的光阴中由简及繁吧,可是信任这必定是一次美好的路程。
6结论
Metadata形貌了静态的布局,而IL阐释了静态的实行,这一静一动承载了太多的手艺奥妙。
当这篇文章即将停止的时分,我发明牵一发而动满身,由此引进的新成绩接二连三,办法挪用、程序集、程序域、CLR加载历程在元数据和IL的剖析中一目了然,也使令我投进注重在前面的《你必需晓得的.NET》中,将这些内容逐一过招。由此才干在庞大的观点和实质之余,由点及面的对一切内容综合掌控,构成周全的懂得和一条线贯串的熟悉,那末将来Anytao将要持续分享另有:

<br>系列预报

[*]程序集和模块
[*]程序域
[*]CLR加载历程
[*]JIT编译
[*]办法挪用
[*]反射各种
[*]其他…
anytao.com
限于忙碌的缘故原由,我没法给出一个明晰的工夫表,但力争每次的内容都给您出充足的劳绩,假如你对.NET一直心胸兴趣,那末敬请等候《你必需晓得的.NET》更多出色。参考文献


[*]《你必需晓得的.NET》第3章“统统从IL入手下手”
[*]DonBox,《.NET实质论》
[*]http://www.sloppycode.net/articles/inside-net-assemblies-and-metadata.aspx
[*]http://www.codeproject.com/KB/dotnet/dotnetformat.aspx
来自:http://www.ckuyun.com/anytao/archive/2009/03/04/must_net_26.html
因为二次编译器太复杂,那么建议只是在安装程序的时候编译一次,而不类似net网页编程那样运行就编译。并且我觉得,一次痛苦,总比多次低效率要舒服多了。

谁可相欹 发表于 2015-1-20 19:18:03

PHP的源代码完全公开,在OpenSource意识抬头的今天,它更是这方面的中流砥柱。不断地有新的函数库加入,以及不停地更新,使得PHP无论在UNIX或是Win32的平台上都可以有更多新的功能。它提供丰富的函数,使得在程式设计方面有着更好的资源。目前PHP的最新版本为4.1.1,它可以在Win32以及UNIX/Linux等几乎所有的平台上良好工作。PHP在4.0版后使用了全新的Zend引擎,其在最佳化之后的效率,比较传统CGI或者ASP等技术有了更好的表现。

变相怪杰 发表于 2015-1-29 09:07:06

ASP.Net摆脱了以前ASP使用脚本语言来编程的缺点,理论上可以使用任何编程语言包括C++,VB,JS等等,当然,最合适的编程语言还是MS为.NetFrmaework专门推出的C(读csharp)。

简单生活 发表于 2015-2-2 17:54:53

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

山那边是海 发表于 2015-2-8 03:27:00

是指转换后的Servlet程序代码的行数。这给调试代码带来一定困难。所以,在排除错误时,可以采取分段排除的方法(在可能出错的代码前后输出一些字符串,用字符串是否被输出来确定代码段从哪里开始出错)。

透明 发表于 2015-2-9 22:38:25

ASP.net1.1和2.0在程序上的语法也有很大不同,现在2.0属于新出来的,不知道半年后会不会有3.0(说笑一下)。Windows2003系统自动支持ASP和ASP.net环境,不用安装任何程序。Asp.net属于编译语言。ASP的最大不同(ASP属于解释语言)。

小女巫 发表于 2015-2-11 09:03:27

但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。

乐观 发表于 2015-2-12 04:34:01

Asp.net脚本的出现,为ASP空间带来了更高的稳定性,同时也为程序员建站提供更高环境!

小妖女 发表于 2015-2-23 18:32:20

Asp.net:首先来说,Asp.net和Asp没什么关系,看着像是升级版本什么的,其实没什么联系。Asp是脚本编程,用的是ASP语言,而ASP.net用的是C#语言,完全不同的东西。

莫相离 发表于 2015-3-7 09:51:06

平台无关性是PHP的最大优点,但是在优点的背后,还是有一些小小的缺点的。如果在PHP中不使用ODBC,而用其自带的数据库函数(这样的效率要比使用ODBC高)来连接数据库的话,使用不同的数据库,PHP的函数名不能统一。这样,使得程序的移植变得有些麻烦。不过,作为目前应用最为广泛的一种后台语言,PHP的优点还是异常明显的。

兰色精灵 发表于 2015-3-21 12:36:27

比如封装性、继承性、多态性等等,这就解决了刚才谈到的ASP的那些弱点。封装性使得代码逻辑清晰,易于管理,并且应用到ASP.Net上就可以使业务逻辑和Html页面分离,这样无论页面原型如何改变。
页: [1]
查看完整版本: ASP.NET网页设计[你必需晓得的.NET]第二十六回:熟悉元数据和IL(下)仓酷云