有关于资源回收
2005-02-03 04:04
405 查看
最近偶正在关注 C++/CLI ,经常听人在介绍 自动确定性资源回收(Automatic deterministic destruction) 特性的时候,宣称 C# 的 using statement 不能在一行中初始化多个变量,进而说明 C++/CLI 的这一设计多么优秀。虽然后果不是很严重,偶也不是很生气,但是为了开始在 cnblogs 的第一篇文章,我决心要为 C# using statement 平反昭雪!
解读1:自动确定性资源回收 起因:我们这个时代的 GC (of .net) 实在很逊,它们不负责自动回收 FileStream 、SqlDataReader 、Pen 等等许多对象所持有的重要资源。nevertheless,假如你把释放资源的代码放到这些类的 Finalize() 方法中,在理应回收资源的时候, GC 又会很官僚地把那些对象扔到一个叫 Freachable Queue 的地方让他们排队等候。
所以一开始人们都是让持有重要资源的类实现 IDisposable 接口,然后又以 close() 之类的方法进行包装,最后手动释放资源。后来人们发明了 using statement 来半自动地完成这一工作:
using( ADisposableClass foo = new ADisposableClass() )
{
... ...
}
这样在代码被编译成 MSIL 的过程中 C# 编译器会自动生成一个.try / finally 块,并在 finally 中调用 foo.Dispose() 方法,以保证资源的释放。但是人们还是要确保 ADisposableClass 实现了 IDisposable 接口。
经过:Stanley Lippman 认为这样很累,所以他在 C++/CLI 中引入了自动确定性资源回收。其本质是把引用类型的析构函数(确定性析构)自动映射为 Dispose() 方法;添加了一种称为 非确定析构函数 的东东,并把它映射成 Finalize() 方法。
ref class ADisposableClass
{
public:
~ADisposableClass () // map to Dispose()
{
// Do release your resource here
}
!ADisposableClass (){} // map to Finalize()
}
如果我们在某个地方写了这么一行:
ADisposableClass foo(); // 注意这是一个初始化栈变量的语法,但是实际上 foo 还是分配于托管堆中(至少目前如此)。
那么在离开当前作用域之前,foo 会被自动析构。原因是编译器自动插入了一个 .try / fault 块,原理和 using statement 没有任何差别。
结果:我们获得了一种以简洁语法自动管理重要资源的方式。其优势在于我们不必显式实现 IDisposable;不必显式指定作用域;从逻辑上理顺了(确定性)析构函数和Finalize()方法的差别。但是采用栈变量语法初始化的引用变量似乎会造成一些问题,具体请参见 http://blog.joycode.com/lijianzhong/archive/2005/01/10/42762.aspx
解读2:C# 的 using statement 不能在一行中初始化多个变量?
起因:有人认为如果在同一个作用域中需要使用很多包含非托管资源的对象,C# 就一定要使用嵌套的 using statement。
using( A a = new A(...) )
{
using( B b = new B(...) )
{
using( C c = new c(...) )
{
... ...
}
}
}
而 C++/CLI 只要这样写:
A a(...);
B b(...);
C c(...);
经过:偶认为 C++/CLI 的语法在这一点上固然简洁到了家。不过 C# 的写法也不见得一定要这么丑陋。既然大家都实现了IDisposable。我们何必嵌套那么多层呢
:
using( IDisposable a = new A(...), b = new B(...), c = new C(...) )
{
(a as A) ... ...
(b as B) ... ...
(c as C) ... ...
}
结果:虽然表面上的写法有那么一些差别,但是编译成 MSIL 之后,无论是C# using statement、还是 C++/CLI 自动确定性资源回收 甚至 是你自己写的嵌套 try / finally 块,生成的代码都是相差无几的。统统都是 .Try / Finally (Fault) 块的嵌套。所以偶感觉 C++/CLI 的这项特性基本只是个语法层面的小hack,没有什么好拿来当卖点的样子。IMHO,STL.net 才更像是值得人们期待的东东。
解读1:自动确定性资源回收 起因:我们这个时代的 GC (of .net) 实在很逊,它们不负责自动回收 FileStream 、SqlDataReader 、Pen 等等许多对象所持有的重要资源。nevertheless,假如你把释放资源的代码放到这些类的 Finalize() 方法中,在理应回收资源的时候, GC 又会很官僚地把那些对象扔到一个叫 Freachable Queue 的地方让他们排队等候。
所以一开始人们都是让持有重要资源的类实现 IDisposable 接口,然后又以 close() 之类的方法进行包装,最后手动释放资源。后来人们发明了 using statement 来半自动地完成这一工作:
using( ADisposableClass foo = new ADisposableClass() )
{
... ...
}
这样在代码被编译成 MSIL 的过程中 C# 编译器会自动生成一个.try / finally 块,并在 finally 中调用 foo.Dispose() 方法,以保证资源的释放。但是人们还是要确保 ADisposableClass 实现了 IDisposable 接口。
经过:Stanley Lippman 认为这样很累,所以他在 C++/CLI 中引入了自动确定性资源回收。其本质是把引用类型的析构函数(确定性析构)自动映射为 Dispose() 方法;添加了一种称为 非确定析构函数 的东东,并把它映射成 Finalize() 方法。
ref class ADisposableClass
{
public:
~ADisposableClass () // map to Dispose()
{
// Do release your resource here
}
!ADisposableClass (){} // map to Finalize()
}
如果我们在某个地方写了这么一行:
ADisposableClass foo(); // 注意这是一个初始化栈变量的语法,但是实际上 foo 还是分配于托管堆中(至少目前如此)。
那么在离开当前作用域之前,foo 会被自动析构。原因是编译器自动插入了一个 .try / fault 块,原理和 using statement 没有任何差别。
结果:我们获得了一种以简洁语法自动管理重要资源的方式。其优势在于我们不必显式实现 IDisposable;不必显式指定作用域;从逻辑上理顺了(确定性)析构函数和Finalize()方法的差别。但是采用栈变量语法初始化的引用变量似乎会造成一些问题,具体请参见 http://blog.joycode.com/lijianzhong/archive/2005/01/10/42762.aspx
解读2:C# 的 using statement 不能在一行中初始化多个变量?
起因:有人认为如果在同一个作用域中需要使用很多包含非托管资源的对象,C# 就一定要使用嵌套的 using statement。
using( A a = new A(...) )
{
using( B b = new B(...) )
{
using( C c = new c(...) )
{
... ...
}
}
}
而 C++/CLI 只要这样写:
A a(...);
B b(...);
C c(...);
经过:偶认为 C++/CLI 的语法在这一点上固然简洁到了家。不过 C# 的写法也不见得一定要这么丑陋。既然大家都实现了IDisposable。我们何必嵌套那么多层呢
:
using( IDisposable a = new A(...), b = new B(...), c = new C(...) )
{
(a as A) ... ...
(b as B) ... ...
(c as C) ... ...
}
结果:虽然表面上的写法有那么一些差别,但是编译成 MSIL 之后,无论是C# using statement、还是 C++/CLI 自动确定性资源回收 甚至 是你自己写的嵌套 try / finally 块,生成的代码都是相差无几的。统统都是 .Try / Finally (Fault) 块的嵌套。所以偶感觉 C++/CLI 的这项特性基本只是个语法层面的小hack,没有什么好拿来当卖点的样子。IMHO,STL.net 才更像是值得人们期待的东东。
相关文章推荐
- Oracle的关于session的销毁资源回收问题的解决方案
- Oracle的关于session的销毁资源回收问题的解决方案
- 关于及时回收(GC)系统资源的析构对象的的示例
- 关于--托管与非托管,回收资源
- CreateCompatibleBitmap,关于兼容DC的创建与资源回收
- 关于lua和python的垃圾回收的看法
- 关于“此程序集中已使用了资源标识符 "Test.Searchn.resources”问题的解决办法
- IIS进程资源定期回收
- vs2005中关于出现 重复的资源 错误
- struts2.1.8 StrutsPrepareAndExecuteFilter 关于静态资源处理问题。访问classPath下静态资源
- 在知乎上看到一个关于Python资源的很不错的主题,可惜点赞不过400多
- Git 一些关于 Git、Github 的学习资源
- Android 关于系统回收的知识整理
- 关于web项目静态资源路径、action路径的控制问题
- C#垃圾回收和资源管理
- C#资源回收
- (一)关于SWT程序的基本架构,如何使用控件以及使用Image,Font,Color等图形资源内容
- 关于javascript document.createDocumentFragment() 替代insertCell、insertRow这种每次都使用大量的资源导致浏览器崩溃
- DSI405中关于smon和空间回收的内容
- Android 自定义View的资源回收