C# vs C++之二:GC vs RAII
2010-09-30 20:49:59 来源:WEB开发网托管和非托管资源
在C#中,资源分为托管资源和非托管资源两种。GC在回收无用对象资源时,可以自动回收托管资源(比如托管内存),但对于非托管资源(比如Socket、文件、数据库连接)必须在程序中显式释放。
托管资源的回收首先需要GC识别无用对象,然后回收其资源。一般无用对象是指通过当前的系统根对象和调用堆栈对象不可达的对象。对象有一个重要的特点导致无用对象判断的复杂性:对象间的相互引用!如果没有相互引用,就可以通过“引用计数”这种简单高效的方式实现无用对象的判断,并实现实时回收。正是由于相互引用的存在导致GC需要设计更为复杂的算法,这样带来的最大问题在于丧失了资源回收的实时性,而变成一种不确定的方式。
对于非托管资源的释放,C#提供了两种方式:
1.Finalizer:写法貌似C++的析构函数,本质上却相差甚远。Finalizer是对象被GC回收之前调用的终结器,初衷是在这里释放非托管资源,但由于GC运行时机的不确定性,通常会导致非托管资源释放不及时。另外,Finalizer可能还会有意想不到的副作用,比如:被回收的对象已经没有被其他可用对象所引用,但Finalizer内部却把它重新变成可用,这就破坏了GC垃圾收集过程的原子性,增大了GC开销。
2.Dispose Pattern:C#提供using关键字支持Dispose Pattern进行资源释放。这样能通过确定的方式释放非托管资源,而且using结构提供了异常安全性。所以,一般建议采用Dispose Pattern,并在Finalizer中辅以检查,如果忘记显式Dispose对象则在Finalizer中释放资源。
可以说,GC为程序带来安全方便的同时也付出了不小的代价:一则丧失了托管资源回收的实时性,这在实时系统和资源受限系统中是致命的;二则没有把托管资源和非托管资源的管理统一起来,造成概念割裂。C++的定位之一是底层开发能力,所以不难理解GC并没有成为C++的语言特性。虽然我们在C++0x和各种第三方库都能看到GC的身影,但GC对于C++来讲并不是那么重要,至多是一个有益的补充。C++足以傲视C,并和C# GC一较高下的是它的RAII。
- ››VSFTP服务器配置详解
- ››gcc内置的for each
- ››VS2008 安装失败(“Web 创作组件”无法)的解决办...
- ››VS调用存储过程
- ››VS2005无法远程连接SQL数据库问题
- ››VS2010 Express中文版已经发布至MSDN
- ››VS2008C# 开发 Windows Mobile 6.0程序应注意的几...
- ››VS08中最简单也最实用的Ajax无刷新技术
- ››VS2003+nds OR VS2003+carbide.vs 开发 Symbian 程...
- ››VS2008 平台下进行 Windows Mobile 开发环境的搭建...
- ››VS 2010/.NET 4 RC版 发布了
- ››VS 2010的Intellisense相关崩溃的修补
更多精彩
赞助商链接