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

引用:
个人觉得资源管理,大多数也就是程序员需要指定什么时候申请什么时候释放,和程序员不需要指定什么时候申请和释放。后者显然方便,而且在后者的性能或者坏处不大的情况下会被认为是比较先进的。
这段话的意思,似乎你觉得一般情况下,人做的管理都比一个同样是人设计实现的、毫无智慧可言的技术差?还是说只有少数人有能力管理资源,于是他们做了gc?如果要我在人和由人所设计的东西之间选择,我会选择人,因为人所设计的东西目前还没有一样有着与人同样水平的智慧。

引用:
对于需要指定什么时候释放的,stack/FIFO/using只能cover一些情况。还有其他情况它的生命周期是动态的,就需要分析生命周期然后去手动调用类似alloc/free的函数。这个比起完全不用管的模式要麻烦也比较容易出错。
......
如果把那些general的需要手动回收的资源管理全都绑定到内存上,然后放弃自动内存管理......
固定的生存期模型的表达能力自然是有限的。你的观点*似乎*是:因为这些模型的表达能力有限,所以干脆就放弃,去寻找一种表达能力无限的模型。而我的观点是:要寻找更多的、多样化的模型来互相填补表达能力的空白。我觉得,表达能力无限的模型,意味着其对应用的假设比较少,而假设少意味着它很难进行针对性的优化。虽然假设越多,那么对使用的限制也就越多,但是当我们有了多种不同的手段时,使用它们互相配合也能解决问题,而且每个手段都能够针对它们所针对的领域进行针对的优化。
我个人的经历中,链表/数组用得比树多,度数固定的树比度数不定的树用得多……我的看法就是,因为链表/数组的约束比树强,所以虽然表达能力可能不如树,但是却更好用,因为我们知道得也多。如果是个图,而且还是个没有什么约束和约定的图,那么能够做的针对性优化就会少很多。

引用:
完全不用管的模式,比如内存和CPU. 内存有gc, CPU有OS. 都不需要你写代码控制。对于CPU完全交给OS我们已经很习惯了,就是内存好像还有不少人还当宝贝一样……
其实……OS只是负责在不同线程之间分配CPU资源,但是当你的线程拿到这些资源(或使用资源的机会)后,怎么使用它们是你自己的事情。内存也是类似的。OS只是在进程层面进行管理,而分配给你的进程的那些内存,OS就不去过问细节了,怎么使用是你自己的事情。
再说内存的确是宝贝,用户买内存也是要钱的……更何况内存的地址空间也是有限的……


引用:
现在如果把那些general的需要手动回收的资源管理全都绑定到内存上,然后放弃自动内存管理......
把非内存管理绑定到内存管理上,并不必然要求放弃自动内存管理。RAII就能把非内存资源绑定到自动管理的内存上(比如栈、内存池)。如果不能绑定(或绑定后的效果不好),我会说是这种内存管理机制的能力不够,而不会说绑定本身是错的。如果内存管理机制无法使用绑定,那么意味着使用这种自动机制就意味着要重新去做非内存资源的管理,这是在解决了一个问题(内存管理)的同时使其他问题(非内存管理)更加严重(原来还能通过RAII之类借用内存管理的一些功能,现在却不能了)。

内存管理并不是一点错都不能有,就好象如果有内存泄漏,但是不严重,那么有时可能也是可运行、可用的。而其他资源也未必那么容易管理。你也说了,其他资源的恢复也只是“可能”可以如何如何,这样内存管理也可以说“可能不是致命的错误”,比如轻微的内存泄漏。
其他资源的“重新初始化”,其实意味着在丢弃错误状态的同时也可能丢弃一些用户需要的信息。而如果其他资源的使用有错,那么可能会比内存访问出错的问题更加隐蔽,可能一直到它被实际部署时才会显露出来。
所以我也可以说,无论是内存管理还是非内存管理,都不是能够甩手不管的事情。

至于绑定的意义,我之前也说过的。
1.各种资源都有生命期管理的问题。
2.生命期管理是个麻烦的问题。要做到在最合适的时间启动生命期,并且在最合适的时间结束生命期,这是一件很困难的事情。
如果:
1.内存的生命期管理做好了
2.能够把非内存资源绑定到内存资源上
那么:
非内存资源的管理就能够借用内存管理机制中的生命期管理功能,这样生命期管理这个大麻烦就只需要在内存管理里面实现一次。
当然,如果把内存地址当成文件描述符那种抽象的资源标识,并且生命期管理是针对内存地址而不是真正具体的内存块,那么可能只需要把非内存资源绑定到内存地址上(就像把设备绑定到文件描述符上)而不需要真正绑定到具体的内存块上。
绑定的必要性就是:同样的生命期模型不应该在不同的资源管理机制中被重复实现。

说实话,如果没有绑定能力,那么各种内存管理机制对我的吸引力将大打折扣,因为我只能用它们做一件事,而本来我通过绑定能够依靠它们做更多的事的。


关于最后那些“机械的事”,你所说的“让编译器/执行环境/类库来做”,具体是指做哪些事?是做“生命期分解”,还是生命期实现,还是生命期分析,或者其他的什么?
生命期分解和生命期分析,我觉得根本上只能靠人,最多使用一些程序工具。毕竟能够真正理解需求的是人而不是程序。
生命期实现,这个*应该*是由编译器/执行环境/类库来做的。应用程序员要做的,就是在已有的各种生命期实现中进行选择和搭配。
栈是一种生命期实现,gc也是;前者能够表达的问题范围更窄,后者的表达范围更广;前者在其针对的领域内能够比较紧密地包裹对象的理想生命期,后者会有延后释放问题。
回复时引用此帖