.Net Framework 之 托管代码和非托管代码的区别
一、什么是托管代码(managed code)?
托管代码:是微软的中间语言(IL),即微软中间语言MSIL(Microsoft Interspace Language)。
“ 源代码→机器码 ”运行分为两个阶段:
1 源代码 → 编译(csc.exe为C#编译器) → 托管代码(即IL),(所以源代码可以有很多种,如VB,C#,J#);
2 托管代码 → 编译(JIT即时编译器) → microsoft的平台专用语言(即机器码)。
注:VS 自带编译器,编译C/C++的cl.exe,编译C#的csc.exe。在“ VS的安装目录→VC目录→vscvarsall.bat ”,把它拖进命令提示符中,回车运行后就能单独使用编译器。
托管代码主要的作用是在.NET Framework的公共语言运行库(CLR)执行代码前去编译源代码,也就是说托管代码充当着翻译的作用,
A、编译器把源代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码。中间语言被封装在一个叫程序集(assembly)的文件中,程序集中包含了描述所创建的类,方法和属性(例如安全需求)的所有元数据。可以拷贝这个程序集到另一台服务器上部署它。
B、托管代码在公共语言运行库(CLR)中运行。这个运行库给运行代码提供各种各样的服务,通常来说,CLR会加载和验证程序集,以此来保证中间语言的正确性。当某些方法被调用的时候,运行库把具体的方法编译成适合本地计算机运行的机器码,然后会把编译好的机器码缓存起来,以备下次调用,这个过程就是即时编译。随着程序集的运行,运行库会持续地提供各种服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。
Visual Basic .NET 和 C#只能产生托管代码。如果用这类语言写程序,那么所产生的代码就是托管代码。Visual C++ .NET也可以生成托管代码,当你创建一个项目的时候,选择名字是以.Managed开头的项目类型。例如.Managed C++ application。
二、什么是非托管代码(unmanaged code)?
非托管代码就是在Visual Studio .NET 2002发布之前所创建的代码。例如Visual Basic 6, Visual C++ 6。最糟糕的是,连那些依然残存在你的硬盘中、拥有超过15年历史的陈旧C编译器所产生的代码都是非托管代码。托管代码直接编译成目标计算机的机器码,这些代码只能运行在编译出它们的计算机上,或者是其它相同处理器或者几乎一样处理器的计算机上。
非托管代码不能享受一些运行库所提供的服务,例如安全和内存管理等。如果非托管代码需要进行内存管理等服务,就必须显式地调用操作系统的接口,通常来说,它们会调用Windows SDK所提供的API来实现。就最近的情况来看,非托管程序会通过COM接口来获取操作系统服务。
跟Visual Studio平台的其他编程语言不一样,Visual C++可以创建非托管程序。当你创建一个项目,并且选择名字以MFC,ATL或者Win32开头的项目类型,那么这个项目所产生的就是非托管程序。
主要区别:
1、托管代码是一种中间语言,运行在CLR上;
非托管代码被编译为机器码,运行在机器上。
2、托管代码独立于平台和语言,能更好的实现不同语言平台之间的兼容;
非托管代码依赖于平台和语言。
3、托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要自己完成这些操作;
非托管代码需要自己提供安全检测、垃圾回收等操作。
托管代码就意味着托管数据?答案是否定的。
对于Visual Basic和C#来说,因为没有其它选择,只能生成托管代码。当在那些语言里面声明一个类,那么这个类的实例会在托管堆中被创建,垃圾收集器(GC)会帮我们管理这些对象的回收。但是在Visual C++中,有另一个选择。即使你正创建一个托管程序,你可以决定哪些类是托管类型,哪些类是非托管类型的。
非托管类型如下:
class Foo {
private: int x;
public: Foo(): x(){}
Foo(int xx): x(xx) {}
};
托管类型如下:
__gc class Bar {
private: int x;
public: Bar(): x(){}
Bar(int xx): x(xx) {}
};
他们唯一的区别就是类Bar的定义中有__gc关键字。这个关键字会给代码带来巨大的区别。
托管类型是可以被垃圾回收器所回收的。他们必须要用关键字“ new ”来创建,永远都不会在栈中出现。所以下面这行代码是合法的:
Foo f;
但是这一行代码就是非法的:
Bar b;
如果我在堆中创建一个Foo对象,那么我必须要负责清理这个对象:
Foo* pf = new Foo(2); // . . . delete pf;
C++编译器实际上会用两个堆,一个托管堆和一个非托管堆,然后通过对new操作符的重载来实现对创建不同类型类的实例,分配不同的内存。如果我在堆里面创建一个Bar实例,那么我可以忽略它。当没有其他代码在使用它的时候,垃圾回收器会自动清理这个类,释放其占用的资源。 对于托管类型会有一些约束:它们不能实现多重继承,或者继承于非托管类型;它们不能用 friend 关键字来实现私有访问,它们不能实现拷贝构造函数。所以,你有可能不想把你的类声明为托管类型。但是这并不意味着你不想让你的代码成为托管代码。在Visual C++中,你可以选择。
三、托管代码与非托管代码的性能比较
基本上每个人都知道的是,所有.Net语言都将被编译成为一个叫做IL汇编的中间语言。但是计算机是如何执行这个中间代码的,却是很多人不知道,甚至理解错误了的。
JIT是.NET程序运行的重要部件之一,全称是即时编译器。很多人(绝对不是少数,问了很多c++程序员,10个有9个这种想法)都以为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的具体类型,可以充分利用这些附加指令集进行编译,这样的性能提升是很可观的。
.Net Framework 之 托管代码和非托管代码的区别的更多相关文章
- Net Framework 中托管代码与非托管代码的区别
托管代码与非托管代码的区别 1 简单的说,就是代码被编译成MSIL后在.net的Framework下运行,同操作系统底层的交互都交给framework去做. 所谓非托管代码就是脱离了Framework ...
- Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用
一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...
- C#基础知识之托管代码和非托管代码
什么是托管代码(managed code)? 托管代码(Managed Code)就是中间语言(IL)代码,在公共语言运行库(CLR)中运行.编译器把代码编译成中间语言,当方法被调用时,CLR把具体的 ...
- .net组件和com组件&托管代码和非托管代码
com组件和.net组件: COM组件是非托管对象,可以不需要.NET框架而直接运行,.NET框架组件是托管对象,必须有.NET框架的支撑才能运行. COM组件有独立的类型库文件,而.NET组件是通过 ...
- C#托管代码、非托管代码及回收机制
网上找了下相关文字,发现一些很不错的,转过来,方便以后查看 托管代码 托管代码就是Visual Basic .NET和C#编译器编译出来的代码.编译器把代码编译成中间语言(IL),而不是能直接在你的电 ...
- .NET托管代码和非托管代码
.net托管代码是运行在.NET FRAMEWORK上的,类似于JAVA虚拟机托管代码:属安全代码,因为不涉及指针,但相对性能上较低,C#写出来的东西就可以认为是托管代码非托管代码:非安全的,可以使用 ...
- c#的托管代码和非托管代码的理解
理解托管和非托管代码的前提之下,要先了解CLR(公共语言运行库) .Net Framework 是由彼此独立又相关的两部分组成:CLR 和 类库, CLR是它为我们提供的服务,类库是它实现的功能. . ...
- 【笔试&面试】C#的托管代码与非托管代码
1. C#中的托管代码是什么? 答:托管代码(ManagedCode)实际上就是中间语言(IL)代码.代码编写完毕后进行编译,此时编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器 ...
- Entity Framework中IQueryable, IEnumerable, IList的区别(转载)
原文:http://www.cnblogs.com/hiteddy/archive/2011/10/01/Difference_among_IQueryable_IEnumeralb_IList_in ...
随机推荐
- Codeforces 1082 A. Vasya and Book-题意 (Educational Codeforces Round 55 (Rated for Div. 2))
A. Vasya and Book time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- ZOJ 3498 Javabeans
脑筋急转弯. 如果是偶数个,那么第一步可以是$n/2+1$位置开始到$n$都减去$n/2$,后半段就和前半段一样了. 如果是奇数个,那么第一步可以是$(n+1)/2$位置开始到$n$都减去$(n+1) ...
- 【leetcode】200. Number of Islands
原题: Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is s ...
- VB查询数据库之组合查询——机房收费总结(二)
在机房收费系统中,组合查询用的还是挺多的,像上机状态查询窗体.学生上机统计信息窗体.操作员工记录窗体.基本信息维护窗体.这其中,学生基本信息维护窗体中的东西比较多,就以它为例子,说说组合查询吧! 学生 ...
- 「NOI2018」归程
「NOI2018」归程 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 >\(1\) 个节点. \(m\) 条边的无向连通图(节点的编号从 \( ...
- 【20181024T1】小C的数组【二分+dp】
题面 [正解] 题目求最大的最小,可以二分 设\(f_i\)表示第i个数不改满足条件需要改多少个 可以从j转移,那么[j+1,i]的均匀摊开后的差值应该在范围内 容易推出方程: \(f_i=min_{ ...
- 【map】【分解质因数】CDOJ1572 Espec1al Triple
先把公比为1,即前项 中项 末项相同的统计出来.对每一类数C(n,3)即可. 然后我们发现,因为a1*a3=(a2)^2,所以a1和a3进行质因子分解之后,每一个质因子的指数的奇偶性必然相同,否则无法 ...
- MySort
实验概述: 本次试验的内容:模拟实现Linux下Sort -t : -k 2的功能.参考Sort的实现.提交码云链接和代码运行截图. 截图如下 实验过程 在实验课上真的很崩溃,可以说脑子里一团乱麻,下 ...
- Python学习笔记 | 关于python数据对象 hashable & unhashable 的理解
文章目录 写在前面 hashable & unhashable mutable & immutable 实例检测 后续思考 参考文章 写在前面 Hash(哈希.散列)是一个将大体量数据 ...
- nginx负载均衡upstream参数配置
一定要注意两台机器能够telnet 访问通过 如果不能通过则两台机器都执行一下 iptables -F 机器A: php-fpm配置[www]user = wwwgroup = wwwlisten ...