回复: 请教各位大大关于动态内存管理的问题…… 查了一下,似乎using/Dispose和栈的区别不大——除了语法上没有栈简洁之外……
而栈的确是我心目中最最优先使用的资源管理技术。
但是,当对象分配在栈上时,构造函数和析构函数仍然是有效的,实际上这是很重要的特点:
用花括号对/栈来说明一个生存期 + 栈上对象的构造函数和析构函数被自动绑定在所在的生存期边界上
1.资源管理是很重要的
2.资源管理是很麻烦的
3.gc机制只能用于管理内存,并且使用它也是有成本的(特别是学习它和理解它的成本)
4.栈、内存池、智能指针都可以把非内存资源绑定上去进行管理
1+2+3+4 ==> 所以我把gc放到候选列表的末尾。
资源的确太广泛了,但正因为如此,我们才需要一个通用的技术。否则内存一个管理技术,文件又是另一个技术……如果没有一个通用技术作为基础,那么最后各种不同的管理机制之间的配合和交互就会成为大问题。
我所期望的资源管理是:
一个良好的内存管理机制+一套把任意行为绑定到内存管理机制上的机制+N套管理各种不同资源的技术
中间那个绑定机制,其实就是C++的构造函数/析构函数。后面那些管理技术是真对于各种资源的,但是它们都应该能够绑定到内存管理上,用内存的生命期来指代各种资源的生命期,这样生命期管理就只需要在内存管理那里实现一次。
现在主要的问题在于最前面那个内存管理机制。栈这样的机制,虽然很好,但是表达力有限;内存池的表达力稍微提高了一些,但是其实主要是比栈多了根据runtime需要而分配的内存的管理能力,生命期模型与栈似乎没多少区别。智能指针存在循环引用问题以及性能问题。所以这些机制大多在表达力上有限,但是虽然它们的表达力有限,但是在其擅长的应用领域里还是用得很好的,所以没有理由丢弃它们。
gc的表达力是最强的,但是如果不考虑性能问题,那么还有一个问题,那就是其不确定性使得把其他资源的管理行为绑定上去后的效果并不好,具体就是在gc环境里使用RAII时的问题。
另外,通用优雅并不是指这个技术需要几行代码,而是说它对外的表现和行为的应用范围和可理解性。
其实,一些os中,很多资源都是以文件描述符的形式出现的,通信就是read/write。这是“通用”的例子。至于即通用又优雅的东西,我一时也想不起来。不过这种追求应该是能取得共识的。
不是我觉得别人看不懂,而是我希望减少别人的负担。如果我把这些控制变量写在实际有意义的范围之外,那么别人就需要花费更多的时间精力来猜测一开始的意图,其实一段时间后可能我自己都不得不进行这样的猜测。如果控制变量多了,代码长了,那么在庞大的代码中到处翻箱倒柜地查看就是很麻烦的事情。一开始的C里,函数的变量必须在函数的前头声明,后来到了C++,连for语句里都可以声明变量了。当实现了一个约束时,一方面是说明这个约束一定会成立,是可以依赖的,另一方面也是说明相应的互斥情况一定不会出现,是可靠的。所以C++里的const是为了提高对设计的表达能力,变量声明的控制以及花括号的作用也是如此。把设计信息以一种良好的方式融入代码,会比写进文档更好。 |