C#基础知识之托管代码和⾮托管代码
什么是托管代码(managed code)
托管代码(Managed Code)就是中间语⾔(IL)代码,在公共语⾔运⾏库(CLR)中运⾏。编译器把代码编译成中间语⾔,当⽅法被调⽤
时,CLR把具体的⽅法编译成适合本地计算机运⾏的机器码,并且将编译好的机器码缓存起来,以备下次调⽤使⽤。随着程序集的运
⾏,CLR提供各种服务:内存管理,安全管理,线程管理,垃圾回收,类型检查等等。
托管代码是⼀microsoft的中间语⾔(IL),他主要的作⽤是在.NET FRAMEWORK的公共语⾔运⾏库(CLR)执⾏代码前去编译源代码,也就是说托管代码充当着翻译的作⽤,源代码在运⾏时分为两个阶段:
源代码编译为托管代码,(所以源代码可以有很多种,如VB,C#,J#)
托管代码编译为microsoft的平台专⽤语⾔
编译器把代码编译成中间语⾔(IL),⽽不是能直接在你的电脑上运⾏的机器码。中间语⾔被封装在⼀个叫
程序集(assembly)的⽂件中,程序集中包含了描述你所创建的类,⽅法和属性(例如安全需求)的所有元数据。你可以拷贝这个程序集到另⼀台服务器上部署它。
托管代码在公共语⾔运⾏库(CLR)中运⾏。这个运⾏库给你的运⾏代码提供各种各样的服务,通常来说,他会加载和验证程序集,以此来保证中间语⾔的正确性。当某些⽅法被调⽤的时候,运⾏库把具体的⽅法编译成适合本地计算机运⾏的机械码,然后会把编译好的机械码缓存起来,以备下次调⽤。(这就是即时编译)随着程序集的运⾏,运⾏库会持续地提供各种服务,例如⾃动垃圾回收、运⾏库类型检查和安全⽀持等。这些服务帮助提供独⽴于平台和语⾔的、统⼀的托管代码应⽤程序⾏为。
Visual Basic .NET和C#只能产⽣托管代码。如果你⽤这类语⾔写程序,那么所产⽣的代码就是托管代码。如果你愿意,Visual C++ .NET 可以⽣成托管代码。当你创建⼀个项⽬的时候,选择名字是以.Managed开头的项⽬类型。例如.Managed C++ application。
什么是⾮托管代码(unmanaged code)
⾮托管代码,直接编译成⽬标计算机码,在公共语⾔运⾏库环境的外部,由操作系统直接执⾏的代码,代码必须⾃⼰提供垃圾回收,类型检查,安全⽀持等服务。如需要内存管理等服务,必须显⽰调⽤操作系统的接⼝,通常调⽤Windows SDK所提供的API来实现内存管理。
当项⽬选择名字以MFC,ATL,Win32开头的项⽬类型,那么这个项⽬所产⽣的就是⾮托管程序。
⾮托管代码就是在Visual Studio .NET 2002发布之前所创建的代码。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,连那些依然残存在你的硬盘中、拥有超过15年历史的陈旧C编译器所产⽣的代码都是⾮托管代码。托管代码直接编译成⽬标计算机的机械码,这些代码只能运⾏在编译出它们的计算机上,或者是其它相同处理器或者⼏乎⼀样处理器的计算机上。⾮托管代码不能享受⼀些运⾏库所提供的服务,例如安全和内存管理等。如果⾮托管代码需要进⾏内存管理等服务,就必须显式地调⽤操作系统的接⼝,通常来说,它们会调⽤Windows SDK所提供的API来实现。就最近的情况来看,⾮托管程序会通过COM接⼝来获取操作系统服务。
跟Visual Studio平台的其他编程语⾔不⼀样,Visual C++可以创建⾮托管程序。当你创建⼀个项⽬,并且选择名字以M FC,ATL或者
Win32开头的项⽬类型,那么这个项⽬所产⽣的就是⾮托管程序。
托管代码和⾮托管代码的区别
1、托管代码是⼀种中间语⾔,运⾏在CLR上;⾮托管代码被编译为机器码,运⾏在机器上。
2、托管代码独⽴于平台和语⾔,能更好的实现不同语⾔平台之间的兼容;⾮托管代码依赖于平台和语⾔。
3、托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要⾃⼰完成这些操作;⾮托管代码需要⾃⼰提供安全检测、垃圾回收等操作。
托管代码与⾮托管代码的性能⽐较
基本上每个⼈都知道的是,所有.Net语⾔都将被编译成为⼀个叫做IL汇编的中间语⾔。但是计算机是如何执⾏这个中间代码的,却是很多⼈不知道,甚⾄理解错误了的。JIT是.NET程序运⾏的重要部件之⼀,全称是即时编译器。很多⼈都以为JIT其实就是跟Java VM差不多的东西,是⼀个Interpreter,在运⾏时读取IL汇编代码,然后模拟成x86代码(也就是俗称的虚拟机)。但是事实上,.NET使⽤的是更为⾼级的技术。 .Net程序被加载⼊内存以后,当某段IL代码被第⼀次运⾏的时候,JIT编译器就会将这段IL代码,全部编译成本地代码,然后再执⾏。这也就是为什么.NET程序第⼀次运⾏都启动很慢的原因! 随.NET库,微软还附带了⼀个⼯具,可以事先将.NET程序所有的IL代码都编译成本地代码并保存在缓存区中,这样⼀来,这个程序就跟c++编译的⼀模⼀样了,没有任何区别,运⾏时也可以脱离JIT了(这⾥不要混淆了,这⾥不是说可以脱离.NET库,⽽是说不需要在进⾏即时编译这个过程了)。所以,请不要将.NET和Java混为⼀谈,两个的运⾏效率根本不是⼀个等级的!
JIT的优化指的是可以针对本地CPU,在编译时进⾏优化。传统程序在编译时,为了保证兼容性,通常使⽤最通⽤的指令集(⽐如古⽼的386指令集)来编译。⽽JIT知道CPU的具体类型,可以充分利⽤这些附加指令集进⾏编译,这样的性能提升是很可观的。
C#托管代码和⾮托管代码
含义
托管/⾮托管是微软的 framework中特有的概念。
⾮托管代码:也叫本地(native)代码。
源程序能直接执行吗
托管代码:是由公共语⾔运⾏库(CLR)执⾏的代码,⽽不是由操作系统直接执⾏。本地代码经过两次编译,第⼀次将源代码编译成中间代码(MSIL,MicrosoftIntermediate Language),第⼆次由中的CLR将中间代码编译成机器代码。程序实际上是被“托管”在公共语⾔运⾏库中。随着程序集的运⾏,公共语⾔运⾏库会持续地提供各种服 务,例如内存管理、安全管理、线程管理等等。和托管资源/⾮托管资源不同,不要弄混。
托管代码的优点
1.跨平台。有关内存管理(内存申请,内存释放,垃圾回收之类的)全部都是的CLR来管理
2.更加安全,不会出现诸如内存泄露之类的问题
托管代码的缺点
1.对程序的性能也产⽣⼀定的影响。CLR⾸次加载程序集代码时,JIT将IL编译成本地代码时,会对其进⾏代码优化,这类似与⾮托管C++编译器的后端所做的事情.这可能也会花费加多的时间⽣成优化代码。
2.不能直接读取内存,不够灵活