| |||
| 另外,最近也终于变成“资源管理”而不是标题上面的“动态内存管理”了。 然后,你那个生命周期管理,我其实写程序的时候希望的只是用那些资源,我不是很想去关心它的生命周期。比如,我想要的只是调用DB, 我不想知道DB conection什么时候open什么时候close, 所以所有的DB access都被包装了一下,变成了一个抽象层,里面的实现如何我调用的时候不关心,只要知道调用里面的函数可以从DB里面取出东西来就是了。然后实现这个抽象层的时候用最直接的写法:每一次访问open一次,然后访问完把数据读回来马上close. 但这样效率就成问题了。每一笔transaction都要数次open/close一个DB connection. 解决这个矛盾的途径是在这个open/close背后还有一个connection pool. 所谓的open只是从pool里面拿一个过来,close只是放回去。pool有一个默认大小,然后会自动增长/缩小。增长按照需求来,缩小的时机不确定(说实话我不知道……只是可能某一些connection好久没人用就会真的被释放掉)。 经过2层抽象,这个DB connection资源的管理其实离我很远了。而那个connection pool在我看来和gc也没有太大的区别,自主调整,但写起来比gc可简单多了。然后第二层上面的open/close很像你所喜欢的stack管理,只是它的作用并不是真的去分配资源和释放资源,而是通知connection pool这个资源是不是可以reuse. 所以我觉得你说的这3点并不是生命周期管理所必需的。 |
| |||
| 引用:
另外,这种需求也很难变化,至少对于那个pool我们的需求没有变化过。它也可以进行一定的配置,但默认的还不错所以我们也没有改过。GC也有一些类似的接口可以configure. pool可以不可以在stack上也是取决于pool的design, 没有必要的feature只会让使用变得复杂。比如上面的ADO.NET的connection pool直接可以这么用: 代码:
引用:
|
| ||||
| 貌似你对基础模块的开发并不感兴趣? 另外又看了一遍你最后那一句,还是看不懂。 “……所以我觉得你说的这3点并不是生命周期管理所必需的。” “我说的那3点的内容是资源管理机制应该符合什么样的标准……如果你使用现成的封装而不需要自己管理资源,自然不需要关心这个……” “不,这个封装未必是现成的,我自己来做恐怕最终成果也就是那样。不会被局限在你那个“确定性”里面,因为它没有带来好处反而局限了抽象。” 不知道这段对话里我哪里提及了“确定性”?我对确定性这个词的解释在前面发过,貌似跟我说的那3点是完全不同的东西……再说确定性跟抽象之间有必然的矛盾吗?你根据我的什么解释得出这样的结论的? 此帖于 2008-03-11 09:26 PM 被 sjinny 编辑. |
| |||
| 引用:
否则的话,gc和pool的满足程度也差不多 1. 使用者很自由,释放的时候只要ref = null就是了 2. gc显然可以保证内存只分配和释放一次。只是释放时间比较松散。 你那个3比较模糊,没有具体例子,不表。 |
| ||||
| 我在gc环境中的析构函数里可以做我想做的任何事吗?如果有限制,有什么样的限制?这种限制相比于栈上的对象析构又如何? 就是因为释放松散,所以我才说“不符合2(主要的问题是延后释放使得生命期包裹不紧密)”…… 无论你看到的是2中的“理想生命期边界上”这几个字、或者看到的是“主要的问题是延后释放使得生命期包裹不紧密”,都应该不会这样误解我的文字……还是那个问题,你有没有仔细看过我的文字?还是一掠而过、根据自己的猜测或者对我已有的结论来回帖?“只是释放时间比较松散”跟“不符合2(主要的问题是延后释放使得生命期包裹不紧密)”有多少区别? 对于3,比如说挂电话这个事件标志着“电话资费计时器对象”的生命期的结束,如果现有程序的结构是消息驱动的,那么我不得不自己在消息处理的代码里手动把挂电话这个事件与ref = null这个操作关联起来。 |
| |||
| 你开始情绪化了。我理解你被人忽略,轻视,不理解的痛苦,不过你也要理解我们在试图谈微积分的时候发现谈话对象还不知道什么叫做一元二次方程的无奈。 你总要求我们耐心给你解释每一个你的知识面没有覆盖的地方,那有没有想过google一下,自我充个电先呢?这“副作用”,“lexical scope”都不是什么生僻的不好搜索的名词。要是你觉得自己查这么多东西比较烦,是不是也就大致理解我们要给你解释谈话中的几乎每一个基本知识点的难度了呢? 此帖于 2008-03-11 10:58 PM 被 ajoo 编辑. |
| |||
| 看得出有情绪化。我还是看你的文字的,但是感觉上还是有疑问,所以反问,不过看了你的澄清还是觉得没完全得到point. 你也仔细考虑一下那些实际而适当具体的例子。或者你能不能也举一个实际而适当具体的scenaio来说明你的需求? 引用:
来一点代码: 代码:
这只是一个语法上面的技巧而以。对象的生命周期还是{}范围内。这是前面很篇幅吵架的第一点:对象生命期和内存管理没有必要绑定。 如果抛开内存细节,我觉得你想找一些管理对象生命期的模式。但是却一直拒绝允许一定随即性的暗箱操作的模式。但后面这种模式确是也是主流的,并且很方便。 再回头看你想要的管理模式: 引用:
所以感觉上你的需求有问题,所以先讨论你的需求的合理性。对于需求不合理的前提下去讨论,意义就不大了。另外,如果用不符合你的3点的管理技术蓬勃发展并且工作地很好,你想找的那种自然就很难找到。 此帖于 2008-03-11 11:47 PM 被 cat 编辑. |
| |||
| 引用:
![]() |
| ||||
| 当我花费时间回帖时我总是感觉到绝大多数的内容都不太可能被人仔细阅读……这样都能保持平静我是做不到的。至少是从我的角度看,你的确没有好好看我的帖子。 对于C++/CLI不熟悉。 但是对于你那个例子,我有个疑问:因为这个例子里仍然是确定性的生命期模型——程序员能够很明确的知道r的生命期。如果程序员不知道,而不得不采用智能指针或gc呢?也就是之前我也提过的问题:当无法使用栈和内存池的时候,有什么机制能够处理这种情况?而且仍然能够在析构函数或等价物中绑定其他操作?另一方面,如果采用了内存扫描,那么能不能确保在同一次collect过程中被释放的对象的释放顺序?比如一些对象在生命期结束时会把当前状态写入log,而这一操作是依赖于某个log对象的,而使用的log对象可能并不一直是同一个对象,这样当普通对象和log对象在同一次collect过程中被回收时,是否能确保log对象最后被回收?如果在两次collect之间,一批普通对象和对应的log对象都失去了来自根的直接或间接的引用,那么就可能在同一次collect中被一起回收。 至于你所描述的周期边界。第一,紧密包裹如果产生不良效应,那么你可以修改生命期模型,使它变得松散,可是如果反过来,你发现现有机制过于松散时,却并不一定能够使它变得更紧密。第二,通过增加间接层(比如叫做Session),session的生命期会紧密包裹一次调用,那么这也能解决问题。 一个能够提供更精密操作的机制,可以给你提供更大的余地;而反过来要使一个不那么精密的机制工作得更精密,却是件很难的事情。不能用误用来证明精密机制反而更糟…… 好像我所列出的那些机制里,还没有哪个机制是3点里全都不符合的……不知道你的“不符合”是具体什么含义……如果是说“不完全符合”,那么我要说,我要找的是能够互相填补空白的工具集合,而不是一个完美的工具…… |
| |||
| 引用:
我觉得这个很general就是case by case地分析。程序员如果一直没有机会知道什么时候释放那就没法释放了,他总有一刻会知道“该释放了”,针对这个条件作适当的薄记然后在条件达到的时候释放就是了。不过很general, 没啥用……不scope down貌似很难给出一个具体的solution |