查看单个帖子
  #114 (permalink)  
旧 2008-03-11
sjinny 的头像
sjinny sjinny 当前离线
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

原来你们不证明是因为你们的观点是“不证自明”的……那我是不是可以理解为,因为你们认同自己的观点,所以你们不需要证明自己的观点;因为你们不认同我的观点,所以我需要证明我的观点?这样的逻辑就不是讨论的态度,是争执的态度。争执就是说服与被说服的关系,讨论是获得新知的过程。
我们寝室里在讨论问题的时候,至少不会有谁说自己的观点是“不证自明”的……哪怕是教科书,里面的观点也不会这么说……在数学里,“不证自明”的公理也是尽量要定理化的……
希望只是我误解了cat的意思……


我已经重复了很多次很多次很多次了:各种资源管理的共同点之一就是生命期管理。生命期管理的失误会导致分配和施放的实际执行的时机不合适,过早释放导致野指针,过晚释放导致内存泄漏,而这两个问题恰恰是难点。
我从来都没想要用一种一成不变的办法来完全解决大量不同的问题。但是,虽然没有方法能够完全解决大量不同的问题,但是这不代表不存在一种方法能够解决大量不同问题中的共同的那部分。各种资源的确有所不同,但是生命期管理是共同的内容,也是最难、最关键的内容(不知道是不是“之一”)。
生命期管理并不一定是显式指定生命期边界的管理方法。无论是引用计数还是scope,这都是具体的方法,但它们都是生命期管理。
对于事件驱动,我假设一般都会存在一个机制来把行为绑定到事件上:比如回调,比如消息,比如轮训……总之能够在发生事件时调用我制定的行为。实际上如果只是“挂电话”这种事件,那么由于事件很容易分辨,所以很容易就把资源释放与事件绑定起来。但是对于“最后一个指向该内存块的指针改变了指向”这种事件,就不那么容易分辨:为了分辨这一事件,使得引用计数不得不使用一个额外的数据来记录引用的数目,多线程环境下的问题也是由这个额外的东西(的访问和维护)引起的。
如果你说的“要说把它推广到普通情况”的含义是指“用上面的事件所对应的管理代码来管理UI里的资源”,那我要说我一直强调的我所认为的共同的问题并不包括这些:这些里面主要都是生命期边界上所调用的行为,而不是生命期边界本身的确定和触发机制,而剩下的消息机制则的确是通用的东西。


我想还是一个问题一个问题的来吧:
目前我想了解的是大家对这个问题的看法:
当找到了一个或一组机制,能够比较好地解决生命期管理的问题后,这样的机制对各种资源的管理是否有很大的帮助?
这里的“生命期管理”是指:
能够按照使用者的要求,把使用者所指定的“分配”行为和“释放”行为绑定在被管理对象的生命期边界上。
1.管理机制对使用者所指定的分配行为和释放行为没有太多约束
2.管理机制确保将会按照使用者所描述的理想生命期边界上调用一次且仅一次。
3.管理机制能够提供充足的方法,让使用者选择和组合这些方法,以获得能够覆盖绝大多数生命期模型的表达力,因此这些不同的方法之间应该是尽量正交的。
这里的生命期边界指“生命期开始”或“生命期结束”这样的时机。而使用者将根据自己所能够获得的信息,向管理机制描述被管理对象的生命期模型。这里的被管理对象,可以是内存块,也可以是任意概念(比如对象、ID值、mutex、文件描述符等)。
现有机制的状体:
栈:符合1,接近2(栈对生命期的包裹一般是“比较紧密的”,只不过距离理想的程度还有小小的距离),不符合3(虽然栈能够与其他机制配合,但是其自身的表达力很有限,所以只能作为多种方法中的一个)。
内存池:符合1,接近2(内存池的包裹程度比栈还要松散一点,但是这经常也是因为程序员对生命期掌握的程度比较低,所以才选择内存池而不是栈),不符合3(同栈)
智能指针:符合1,很接近2(如果能把各种事件和条件良好地映射到智能指针的持有和丢弃上,那么生命期包裹还是很紧密的),接近3(表达力比栈和内存池更强,但是对于以特定条件或事件的组合来确定生命期边界的情况没有提供直接的支持,有时可能需要手动用智能指针对象来把事件映射到生命期管理中)
gc:不符合1(毕竟gc*经常*是应用线程之外的独立线程,而且collect的时候还需要停止应用线程的工作[至少要暂停对被collect的内存区域的访问],当然更重要的还是时机的不确定性,所以限制会多一些),不符合2(主要的问题是延后释放使得生命期包裹不紧密),接近3(其实这个方面的问题跟智能指针是类似的——某些生命期模型下需要使用者自己做一些从事件到管理的映射)。

如果想讨论资源管理,我建议从以上这个问题开始。

此帖于 2008-03-11 09:30 PM 被 sjinny 编辑.
回复时引用此帖