返回   cpper编程论坛 > 技术杂烩
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

技术杂烩 找不到地方的技术问题?这里!

回复
 
LinkBack 主题工具 显示模式
  #121 (permalink)  
旧 2008-03-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

另外,最近也终于变成“资源管理”而不是标题上面的“动态内存管理”了。

然后,你那个生命周期管理,我其实写程序的时候希望的只是用那些资源,我不是很想去关心它的生命周期。比如,我想要的只是调用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点并不是生命周期管理所必需的。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #122 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

既然你知道“每一次访问open一次,然后访问完把数据读回来马上close”或者“pool”机制,那么你就是知道db连接的生命期的,如果你不知道,如何设计这些?或者说如果你不是使用别人封装好的东西,那么你仍然不得不知道……

pool和gc是很不同的……因为gc是独立线程,而且你无法修改它的代码来适应需求变化……但是pool如果作为一个模块,那么是可以合并到上层应用的线程中的,这样对于pool中的资源的分配和释放,其行为限制会小一些,因为你可以避开线程问题。而且作为一个模块,pool最终是可控的——你可以了解其背后的行为,你可以在其代码的层面来修改和定制。而且pool本身也可以放在栈中,可以说其与栈机制是不矛盾的……pool中也可以有pool,可以实现层级管理……
“缩小的时机不确定”对于非独立线程pool应该很难实现……因为对于非独立线程pool,只需要单步跟踪就能知道在什么情况下会缩小,除非你没有它的源码……但是哪怕自己写个pool都可以,相对来说这比gc容易写,而且不像gc那样对语言特性那么挑剔……关键是,这个时机对于pool是确定的,因为pool会在确定的条件下才能获得CPU的使用权(即上层调用其成员函数的时候),而其缩小的条件也是确定的——否则它如何工作?无论如何,程序员对pool的控制力都比gc强得多……
如果说它在你看来和gc没区别,那只能说你只是使用这些组件,而不是自己开发这些组件……从我的角度来看,只能使用别人做好的组件是缺乏安全感的,因为总有一些问题需要自己开发基础组件……

所谓“希望的只是用那些资源,我不是很想去关心它的生命周期”,恐怕只有那些用脚本写游戏逻辑的策划可以这么安逸,大多数时候程序员多多少少都有维护实现层面细节的责任,特别是那些负责底层模块或者库开发的人。

我说的那3点的内容是资源管理机制应该符合什么样的标准……如果你使用现成的封装而不需要自己管理资源,自然不需要关心这个……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #123 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

如果你一直从标题来理解我后续的所有回帖,那我只能说很遗憾……对于那些与标题无关的回帖内容,我不想不给予回应,所以我的回帖自然也不全是针对标题的……
更何况,“资源管理”这个话题有什么问题或者不好的吗?还是说在现在的标题下不应该讨论“资源管理”这个话题?

另外我想重申一下我的最最核心的讨论目的:寻找栈和pool以外的高确定性资源管理机制,以填补栈和pool的表达力薄弱的地方。如果大家对这个不感兴趣,那我也不用再来了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #124 (permalink)  
旧 2008-03-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny
pool和gc是很不同的……因为gc是独立线程,而且你无法修改它的代码来适应需求变化……但是pool如果作为一个模块,那么是可以合并到上层应用的线程中的,这样对于pool中的资源的分配和释放,其行为限制会小一些,因为你可以避开线程问题。而且作为一个模块,pool最终是可控的——你可以了解其背后的行为,你可以在其代码的层面来修改和定制。而且pool本身也可以放在栈中,可以说其与栈机制是不矛盾的……pool中也可以有pool,可以实现层级管理……
pool里面的实现我不清楚,他可能是独立线程监控缩小,可能是每次释放的时候check一下是否需要缩小。这一部分是可以单独优化和配置的。另外,这个pool我没有源代码,是整个framework (ADO.NET)的一部分。我最初也不知道这个pool的存在,只是觉得这么频繁地open/close connection会不会太慢。后来发现多虑了。

另外,这种需求也很难变化,至少对于那个pool我们的需求没有变化过。它也可以进行一定的配置,但默认的还不错所以我们也没有改过。GC也有一些类似的接口可以configure.

pool可以不可以在stack上也是取决于pool的design, 没有必要的feature只会让使用变得复杂。比如上面的ADO.NET的connection pool直接可以这么用:

代码:
using (SqlConnection conn = new SqlConnection(myConnectionString)) { conn.Open(); doSomething(conn); }
哪里都看不到那个pool. 但是他其实存在着。它就没有想要让别人介入它的生命周期。这也使得它非常好用。

引用:
作者: sjinny
我说的那3点的内容是资源管理机制应该符合什么样的标准……如果你使用现成的封装而不需要自己管理资源,自然不需要关心这个……
不,这个封装未必是现成的,我自己来做恐怕最终成果也就是那样。不会被局限在你那个“确定性”里面,因为它没有带来好处反而局限了抽象。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #125 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

貌似你对基础模块的开发并不感兴趣?

另外又看了一遍你最后那一句,还是看不懂。

“……所以我觉得你说的这3点并不是生命周期管理所必需的。”
“我说的那3点的内容是资源管理机制应该符合什么样的标准……如果你使用现成的封装而不需要自己管理资源,自然不需要关心这个……”
“不,这个封装未必是现成的,我自己来做恐怕最终成果也就是那样。不会被局限在你那个“确定性”里面,因为它没有带来好处反而局限了抽象。”

不知道这段对话里我哪里提及了“确定性”?我对确定性这个词的解释在前面发过,貌似跟我说的那3点是完全不同的东西……再说确定性跟抽象之间有必然的矛盾吗?你根据我的什么解释得出这样的结论的?

此帖于 2008-03-11 09:26 PM 被 sjinny 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #126 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

另外我要很惶恐地问cat一句:您有没有把这个主题的帖子从头到尾好好看过一遍?还是一目十行然后就奋笔疾书?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #127 (permalink)  
旧 2008-03-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny
能够按照使用者的要求,把使用者所指定的“分配”行为和“释放”行为绑定在被管理对象的生命期边界上。
1.管理机制对使用者所指定的分配行为和释放行为没有太多约束
2.管理机制确保将会按照使用者所描述的理想生命期边界上调用一次且仅一次。
3.管理机制能够提供充足的方法,让使用者选择和组合这些方法,以获得能够覆盖绝大多数生命期模型的表达力,因此这些不同的方法之间应该是尽量正交的。
因为你在后面讨论gc不符合1和2所以我觉得你还在强调确定性。
否则的话,gc和pool的满足程度也差不多
1. 使用者很自由,释放的时候只要ref = null就是了
2. gc显然可以保证内存只分配和释放一次。只是释放时间比较松散。
你那个3比较模糊,没有具体例子,不表。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #128 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

我在gc环境中的析构函数里可以做我想做的任何事吗?如果有限制,有什么样的限制?这种限制相比于栈上的对象析构又如何?

就是因为释放松散,所以我才说“不符合2(主要的问题是延后释放使得生命期包裹不紧密)”……
无论你看到的是2中的“理想生命期边界上”这几个字、或者看到的是“主要的问题是延后释放使得生命期包裹不紧密”,都应该不会这样误解我的文字……还是那个问题,你有没有仔细看过我的文字?还是一掠而过、根据自己的猜测或者对我已有的结论来回帖?“只是释放时间比较松散”跟“不符合2(主要的问题是延后释放使得生命期包裹不紧密)”有多少区别?

对于3,比如说挂电话这个事件标志着“电话资费计时器对象”的生命期的结束,如果现有程序的结构是消息驱动的,那么我不得不自己在消息处理的代码里手动把挂电话这个事件与ref = null这个操作关联起来。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #129 (permalink)  
旧 2008-03-11
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
另外我要很惶恐地问cat一句:您有没有把这个主题的帖子从头到尾好好看过一遍?还是一目十行然后就奋笔疾书?
你开始情绪化了。我理解你被人忽略,轻视,不理解的痛苦,不过你也要理解我们在试图谈微积分的时候发现谈话对象还不知道什么叫做一元二次方程的无奈。

你总要求我们耐心给你解释每一个你的知识面没有覆盖的地方,那有没有想过google一下,自我充个电先呢?这“副作用”,“lexical scope”都不是什么生僻的不好搜索的名词。要是你觉得自己查这么多东西比较烦,是不是也就大致理解我们要给你解释谈话中的几乎每一个基本知识点的难度了呢?

此帖于 2008-03-11 10:58 PM 被 ajoo 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #130 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

如果你不愿意看我写的东西,那我为什么就要把你提到的东西都拿去正儿八经学一遍?你连看我贴子的时间都没有,却要花更多的时间来回应你吗?我也不是无事可做……还是那句话,要有诚意,不要一副高高在上的样子。没有诚意也没关系,但是不要假装……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #131 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

如果cat能够证明你的确好好看了我的帖子,那我很愿意道歉。如果cat不愿意证明,那我只能说很遗憾……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #132 (permalink)  
旧 2008-03-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

看得出有情绪化。我还是看你的文字的,但是感觉上还是有疑问,所以反问,不过看了你的澄清还是觉得没完全得到point. 你也仔细考虑一下那些实际而适当具体的例子。或者你能不能也举一个实际而适当具体的scenaio来说明你的需求?

引用:
作者: sjinny
我在gc环境中的析构函数里可以做我想做的任何事吗?如果有限制,有什么样的限制?这种限制相比于栈上的对象析构又如何?
析构函数只要不代表内存被释放的话,你需要的东西还是可以做到的。有一个现成的语言就是C++/CLI. 只不过我平时就忍了C#的using语法了。

来一点代码:
代码:
ref class R1 { public: R1() { Show("R1::ctor"); } ~R1() // dispose { Show("R1::dtor"); } protected: !R1() // finalizer { Show("R1::fnzr"); } }; void _tmain() { R1 r; int y=100; }
这个貌似在stack上面的r其实还是在heap上分配的,但是dtor会被自动调用,由于定义了finalizer, 所以内存回收的时候还有机会干点别的。

这只是一个语法上面的技巧而以。对象的生命周期还是{}范围内。这是前面很篇幅吵架的第一点:对象生命期和内存管理没有必要绑定。


如果抛开内存细节,我觉得你想找一些管理对象生命期的模式。但是却一直拒绝允许一定随即性的暗箱操作的模式。但后面这种模式确是也是主流的,并且很方便。

再回头看你想要的管理模式:
引用:
2.管理机制确保将会按照使用者所描述的理想生命期边界上调用一次且仅一次。
我觉得没必要,比如gc管内存(注意:不管生命周期)。再看我那个DB connection pool管数据库连接,我描述的周期边界上立刻释放对于效率甚至是有害的。

所以感觉上你的需求有问题,所以先讨论你的需求的合理性。对于需求不合理的前提下去讨论,意义就不大了。另外,如果用不符合你的3点的管理技术蓬勃发展并且工作地很好,你想找的那种自然就很难找到。

此帖于 2008-03-11 11:47 PM 被 cat 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #133 (permalink)  
旧 2008-03-11
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
如果你不愿意看我写的东西,那我为什么就要把你提到的东西都拿去正儿八经学一遍?你连看我贴子的时间都没有,却要花更多的时间来回应你吗?我也不是无事可做……还是那句话,要有诚意,不要一副高高在上的样子。没有诚意也没关系,但是不要假装……
我有没有“诚意”不重要。你花多少时间写多少字我也必须花多少时间看多少字也好像没有逻辑上的因果关系。当然,这不是你逻辑上犯的第一个错误,也不是最后一个。不过既然你连花时间学一些基础知识都觉得亏了的话,那就一直在这儿斗嘴吧,我继续看热闹。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #134 (permalink)  
旧 2008-03-11
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: cat 查看帖子


析构函数只要不代表内存被释放的话,你需要的东西还是可以做到的。有一个现成的语言就是C++/CLI. 只不过我平时就忍了C#的using语法了。
现在回头看看,是不是:
代码:
auto Foo foo = ...; ...

代码:
using(Foo foo = ...) { ... }
舒服?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #135 (permalink)  
旧 2008-03-11
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: ajoo
舒服?
是啊…… 不过C#还是很舒服的,这些小缺点只能忍了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #136 (permalink)  
旧 2008-03-11
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

当我花费时间回帖时我总是感觉到绝大多数的内容都不太可能被人仔细阅读……这样都能保持平静我是做不到的。至少是从我的角度看,你的确没有好好看我的帖子。

对于C++/CLI不熟悉。
但是对于你那个例子,我有个疑问:因为这个例子里仍然是确定性的生命期模型——程序员能够很明确的知道r的生命期。如果程序员不知道,而不得不采用智能指针或gc呢?也就是之前我也提过的问题:当无法使用栈和内存池的时候,有什么机制能够处理这种情况?而且仍然能够在析构函数或等价物中绑定其他操作?另一方面,如果采用了内存扫描,那么能不能确保在同一次collect过程中被释放的对象的释放顺序?比如一些对象在生命期结束时会把当前状态写入log,而这一操作是依赖于某个log对象的,而使用的log对象可能并不一直是同一个对象,这样当普通对象和log对象在同一次collect过程中被回收时,是否能确保log对象最后被回收?如果在两次collect之间,一批普通对象和对应的log对象都失去了来自根的直接或间接的引用,那么就可能在同一次collect中被一起回收。

至于你所描述的周期边界。第一,紧密包裹如果产生不良效应,那么你可以修改生命期模型,使它变得松散,可是如果反过来,你发现现有机制过于松散时,却并不一定能够使它变得更紧密。第二,通过增加间接层(比如叫做Session),session的生命期会紧密包裹一次调用,那么这也能解决问题。
一个能够提供更精密操作的机制,可以给你提供更大的余地;而反过来要使一个不那么精密的机制工作得更精密,却是件很难的事情。不能用误用来证明精密机制反而更糟……

好像我所列出的那些机制里,还没有哪个机制是3点里全都不符合的……不知道你的“不符合”是具体什么含义……如果是说“不完全符合”,那么我要说,我要找的是能够互相填补空白的工具集合,而不是一个完美的工具……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #137 (permalink)  
旧 2008-03-12
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny
而不得不采用智能指针或gc呢?也就是之前我也提过的问题:当无法使用栈和内存池的时候,有什么机制能够处理这种情况?而且仍然能够在析构函数或等价物中绑定其他操作?
你之前可是把主要精力花在说gc的不是,说内存和生命周期绑定的好处上了呀。注意力都被集中到那里了。

我觉得这个很general就是case by case地分析。程序员如果一直没有机会知道什么时候释放那就没法释放了,他总有一刻会知道“该释放了”,针对这个条件作适当的薄记然后在条件达到的时候释放就是了。不过很general, 没啥用……不scope down貌似很难给出一个具体的solution
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #138 (permalink)  
旧 2008-03-12
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: cat 查看帖子
不scope down貌似很难给出一个具体的solution
这个,啧啧,貌似很欠扁的说。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #139 (permalink)  
旧 2008-03-12
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

sigh 通用优雅的东西拍脑袋想不出啊…… bottom up的方法更适合我这种民工级别的。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #140 (permalink)  
旧 2008-03-12
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: cat 查看帖子
sigh 通用优雅的东西拍脑袋想不出啊…… bottom up的方法更适合我这种民工级别的。
晕!没understand我say的话?还是pretend傻?而且,应该说:
通用elegant的thing拍脑袋也think不出来啊。bottom up的方法更fit我这种民工level的。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码