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

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

回复
 
LinkBack 主题工具 显示模式
  #21 (permalink)  
旧 2008-02-18
liuxinyu 的头像
高级会员
 
注册日期: 2006-02-09
帖子: 303
文章: 48
liuxinyu 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: cat 查看帖子
原来是做游戏的啊 和我这样做网站的就不同了,让PolyRandom妖来表述一下比较好。大概网络游戏的server端稍微有点相同。

BTW, 我们做网站的换硬件用户不掏钱
摁,说起应用领域,不才是做手机平台的。CPU慢就不说了,内存也少得可怜。再有,现在手机要求用户长年不关机,不重启,尤其是在用户拨打110或者119等免费号码报告自己位置的时候,不能重启。

那么说说symbian里面如何管理内存的,说出来极端一点,几乎不在栈上初始化。所有的C类都推荐把构造函数设置为private的,而提供一个static的NewL来强制在堆上初始化。
然后在使用指针前一律推入一个CleanupStack,用好后在pop出来,一旦出了问题,CleanupStack遍历所有推入的对象,一一释放。具体可以参考俺前年的文章:
资源管理的“变法” - C++,算法,设计模式

后半部分给出的就是一个简化的说明。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #22 (permalink)  
旧 2008-02-18
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

Elminster,你这两篇我也看过的,我对你的思路的理解是:对象生存期由程序员控制,内存由gc回收……干脆就放弃了对象和内存的绑定……那么用什么样的机制来保证对象生存期控制的正确性呢?手动析构对象和手动释放内存有同样的问题,要在何时的时机析构。析构过早,要么崩溃,要么抛异常。有时,把崩溃变为异常就够了,但是即使不考虑异常带来的消耗,在很多时候这还是不够的,因为很多时候这只是以两种不同的方式导致了同一个后果:某项操作无法完成,而这个后果可能是个蝴蝶效应的开端。另一方面,把崩溃变为异常也并不需要gc的参与,只要增加一个指针做间接访问就行了。如果需要这个特性,只需要一个允许强制释放对象的内存池(或者说对象池),而不是gc。而析构过晚是由gc来防止的。所以如果把gc抽象的看作一个自动化管理机制,你的思路仅仅是允许强制释放。
如果程序员能够确保在正确的时机析构对象,那么他们也能手工管理内存,那么gc就退居二线而不会有java里那样的地位。对我来说,这只是把gc当作内存管理的“最后保障”而不是常规手段了。
如果程序员不能确保在正确的时机析构对象,那么这种做法就会带来很多错误,只不过不是崩溃而是程序的正确性和功能得不到保障——其实这跟崩溃的差别也不大。


我想我之前的帖子里我还不太清楚我想要什么,现在我明确了:
我想要更多的 高确定性的自动化对象管理机制。
桟是用花括号{}来表示生存期边界,内存对象的生存期不会到达所在生存期的边界之外,同一生存期内的对象按FILO的顺序释放。
内存池是用单个内存池来表示生存期,池中的对象的生存期不会超过内存池自身的生存期,池内对象的释放顺序不定,如果允许池中对象的释放时机提前于内存池的释放,那么要确保访问池中不存在的或已释放的对象时会抛出异常或返回出错码。
智能指针以第一个持有者和最后一个持有者为生存期边界,当最后一个持有者放弃持有时,对象被销毁。如果允许提前释放,那么当访问已释放对象时要抛出异常或返回出错码。
GC是以对象创建和最后一个持有者放弃持有后第一次被gc扫描为生存期边界的。Elminster的想法就是允许提前释放。

我希望有更多的象桟那样的自动机制。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #23 (permalink)  
旧 2008-02-18
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

liuxinyu,后半部分那个方法,意思是不是自己实现一套异常机制?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #24 (permalink)  
旧 2008-02-19
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

to pora:
没有不公平啦,那是后一个release测的,大家觉得还是硬件导致的比重大一点。另外我们的这种online service C++也不敢太关注效率,动不动就crash可不行,宁可慢一点的。反正bottleneck在DB和web service call.

to sjinny:
引用:
Elminster,你这两篇我也看过的,我对你的思路的理解是:对象生存期由程序员控制,内存由gc回收……干脆就放弃了对象和内存的绑定……那么用什么样的机制来保证对象生存期控制的正确性呢?手动析构对象和手动释放内存有同样的问题,要在何时的时机析构。析构过早,要么崩溃,要么抛异常。
那就看你要什么“保证”了。我觉得在实践上,你说的那些情况,基本不可能发生。即便发生了,因为内存还没有被回收,也不会导致很不良的后果。如果你愿意给每一个对象加一个bool _isDisposed的话也可以检查出来。但是要更进一步的严谨的保证的话,你需要为此付出很多代价的,比如写程序的便利性,效率等。不划算。为最后的20%质量可能付出80%的价格,这种奢侈品我可消费不起。

ref counter一看就很慢很浪费,和你一开始说内存小CPU贵矛盾。而且中间漏写/写错这些wrapper就会提前释放或者泄露。这可不是不会发生的事情啊,以前就碰到过,查了好久的说。
这个和你说的一样是“高确定性”和“自动化”的,但是代价却不小。要高效和要自动有的时候是矛盾的。

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

这么晚还在线啊……

实践上发生的概率我也说不清。
ref count的慢和浪费我觉得如果少用那么是可以接受的,按照我心中的优先顺序是:桟 > 内存池 > 智能指针 >= gc。
所以大多数情况下应该把生存期分析清楚了,用前两个来做。我发的这些帖子,就是希望能够找到更多的机制,来填补智能指针之前的空白,毕竟桟和内存池的表达力还是有限的。
其实,自动化的目的是为了减少人脑资源的耗费,而高确定性则是让人比较容易了解系统运行的过程,从而提高可靠性改善的可能以及性能优化的可能。

至于那些wrapper,既然叫做wrapper,那么就是不需要重复写很多遍的东西。很多操作,如果只做一次,人们往往能够做好,要重复做很多遍就难免不出错了。所以把addRef和subRef封装起来后,智能指针的使用就容易了很多。

此帖于 2008-02-19 03:47 AM 被 sjinny 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #26 (permalink)  
旧 2008-02-19
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
这么晚还在线啊……

实践上发生的概率我也说不清。
ref count的慢和浪费我觉得如果少用那么是可以接受的,按照我心中的优先顺序是:桟 > 内存池 > 智能指针 >= gc。
所以大多数情况下应该把生存期分析清楚了,用前两个来做。我发的这些帖子,就是希望能够找到更多的机制,来填补智能指针之前的空白,毕竟桟和内存池的表达力还是有限的。
其实,自动化的目的是为了减少人脑资源的耗费,而高确定性则是让人比较容易了解系统运行的过程,从而提高可靠性改善的可能以及性能优化的可能。

至于那些wrapper,既然叫做wrapper,那么就是不需要重复写很多遍的东西。很多操作,如果只做一次,人们往往能够做好,要重复做很多遍就难免不出错了。所以把addRef和subRef封装起来后,智能指针的使用就容易了很多。
当我们在一个体系里面有多个选择的时候,你说的那个顺序可能没错。问题是,选择越多,错误越多。C++程序写到现在,一点内存错误都没有犯过的人有几个?为什么犯错误呢?往往是该释放的没释放,或者不该释放的释放了。这往往就是程序员在选择方式的时候错了。无论这个“桟 > 内存池 > 智能指针 >= gc”是不是对的,假设我在某个语言/平台上,我只允许你永远使用这些方法中的一个,你会怎么选择呢?事实上,stack不能作为唯一的形式出现,heap可以,但是仅有heap没有stack的情况下,为什么不加入gc呢?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #27 (permalink)  
旧 2008-02-19
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

也许对于某些重复性的事务,机器可以做得比人好,但是我坚信,凡是需要分析、思考和创造的事情,人都能比机器做得更好。我不把编程看作一种重复性事务,至少对于开发游戏引擎的人来说,每一次开发都会与过去有所不同,都需要有所改进和创新。
所以我不喜欢java那样剥夺程序员选择的权力,我更喜欢C++这样尊重程序员的智慧的语言。C#里也是既有桟又有gc,C++09里也会加入可选的gc。

不过另一方面,虽然我喜欢有更多的选择,但是我也承认,选择一般都是个麻烦。我觉得好的设计应该是,为使用者提供更多的选择、更多的可能,但是如果使用者不想选择,那么提供足够好的缺省选项。但是对于程序员这样的用户,一般都会进行选择的吧。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #28 (permalink)  
旧 2008-02-19
liuxinyu 的头像
高级会员
 
注册日期: 2006-02-09
帖子: 303
文章: 48
liuxinyu 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
liuxinyu,后半部分那个方法,意思是不是自己实现一套异常机制?
Symbian操作系统中,没有异常。主要是考虑异常的实现(例如结构化异常)对于手机来说代价很高。另外,早期的Symbian不支持多线程,现在的Symbian虽然勉强支持了,但是仍然不鼓励使用,除非极为特别的情况。

整个这套机制中还有一个重要的前提,就是构造函数是危险的,因为一旦在构造过程中出现内存耗尽,或者资源耗尽。则没有任何人可以回收构造了一半的资源,于是手机只好重启。所以要求构造函数是非public的并且实现必须为空。真正的初始化要被CleanupStack保护好后再进行。

另外,非内存资源,如文件,网络等等,也是通过CleanupStack保护的。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #29 (permalink)  
旧 2008-02-19
liuxinyu 的头像
高级会员
 
注册日期: 2006-02-09
帖子: 303
文章: 48
liuxinyu 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

另外,的确内存管理的方法很多,基本上各有利弊。兼收并蓄,不排斥任何一种方法才是C++的风格(正如C++多范式的特点一样)。当然,这是一个双刃剑。相信使用dos脚本或者unix shell的时候,没有用户会care内存释放的问题,使用python,或者perl等轻量快速脚本的时候,很难想象自己一个一个谨慎delete,或考虑生存期,会多么分散对算法本身的注意力。
并且栈的确有时不够用,因为对象引用的语义是很多程序中不可或缺的。

最后,我还是要提出那个最笨、最不负责任的方法。如果是一次性计算,只申请,不释放,程序结束后统一交给OS回收。这个方法适合相当多的场合。当然你的OS不要太老就足够了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #30 (permalink)  
旧 2008-02-20
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

选择多累啊,如果有人帮忙选好了说用这些就成那才爽呢。老分心想内存有没有漏,异常了漏不漏,活都干不完了……RAII是个好东西,智能指针毛病比较多(搞错语义的事情碰到过的,尤其是copy的时候,以及和Legacy code接的时候必须要脱掉马甲的时候)。

人花时间下去确实可以做出更优化的内存管理(OS的kernel一般很细致),但这个成本是不是值得就要看了。另外就是liu的那个铁律问题,如果到处都要人判断的话,你做的优化被某个人一不小心就搞坏了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #31 (permalink)  
旧 2008-02-20
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

嗯,C++和Java最大的不同就是对待程序员的态度。

cat,我觉得选择既是痛苦也是快乐。试想如果生活中人没有了选择,我觉得就像行尸走肉一样了……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #32 (permalink)  
旧 2008-02-20
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

你可以认为Java不给你选择,而C++给你选择了。但是,你也可以把C++和Java视为两种不同的选择。你喜欢C++的自由,没有人强迫你使用Java,你喜欢被Java虐待,这也是你的自由
这就好像,有人买保险的原因是,他知道他管不住自己,所以需要一份合同来强制自己储蓄 去选择你将来会没有选择的事情,也是选择的一种。
另外,Java与C++之争,和GC与stack之争没关系。正如你前面提到的C#之类的语言,可以证明这两者是不冲突的。所以,讨论到这里,问题何在呢?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #33 (permalink)  
旧 2008-02-20
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

嗯,问题就在于,gc的存在不仅不说明我们可以把确定型管理方法抛弃,而反而恰恰说明确定型管理方法的缺乏。所以现在的问题就是如何开发新的确定型管理方法来弥补桟的表达力的局限。 ^_^
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #34 (permalink)  
旧 2008-02-20
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

pora说得好 选语言是王道。选C#/java/ruby/python/shell可是脱离苦海啊,虽然内存方面没的选了,但其他方面有好多丰富的选择。

确定的且和gc一样(或者几乎一样)方便的没有,所以在gc不会带来太大痛苦的地方,大家就用gc了。

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

我不喜欢把自己的未来绑定到某个语言上…… @_@!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #36 (permalink)  
旧 2008-02-21
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

是啊 表吊在C++上哦
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #37 (permalink)  
旧 2008-02-21
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

呵呵,C++是我所遇见的最尊重程序员的语言了……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #38 (permalink)  
旧 2008-02-23
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

热泪盈眶啊。门前冷落车马稀了这么久,连这种本来我最爱的的月经贴也这么久才出现一个。呜呜呜。。。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #39 (permalink)  
旧 2008-02-23
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

呃……以前有帖子讨论过gc的缺点吗?我没搜到诶
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #40 (permalink)  
旧 2008-02-23
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

别说这种帖子了,帖子都很少…… sigh
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

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

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



所有时间均为格林尼治时间 +9。现在的时间是 07:45 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2008,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0