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

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

回复
 
LinkBack 主题工具 显示模式
  #61 (permalink)  
旧 2008-03-03
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
静态信息的确是不完全的,但是有些东西最好还是让程序员自己来说明。比如说栈,你可以根据代码进行静态分析,让程序自己得出结论某个变量有明确的作用域。可是那只是一种结果,却不能反应程序员的意图。如果像C这样显式地说明栈,那么说明的就是程序员的意图:我不想让栈里的这些变量的作用域泄露到栈外......
这个想法是片面的,我觉得会出问题。
这就好像我去餐馆吃饭,我只要告诉他我要吃宫保鸡丁,最多告诉他要辣还是不辣,那就等着吃了。如果他还让我选择使用花生还是腰果,也许我会更喜欢,但是某些人已经会觉得麻烦了。要是我还得选择用新花生还是老花生,水煮的还是生的,....,我不会再去吃了。自由总是有限的。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #62 (permalink)  
旧 2008-03-03
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

一顿饭只是一次性的,即使端上来的不好吃,也不过将就着把一顿饭吃掉而已。但是软件不一样,一般都希望有可维护性和复用性的,所以灵活性以及软件中所含知识的传递性就很重要了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #63 (permalink)  
旧 2008-03-03
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
一顿饭只是一次性的,即使端上来的不好吃,也不过将就着把一顿饭吃掉而已。但是软件不一样,一般都希望有可维护性和复用性的,所以灵活性以及软件中所含知识的传递性就很重要了。
但是按照你的要求,显然不能使用全局的开关。你需要能够显式地告诉编译器每个变量/对象的方式。其实我很讨厌gc的,我没有用gc写过任何大的东西。但是要是我每个变量都要
fast_register non_nrv_opt try_allocate_on_stack_if_too_large_allocate_on_heap SomeClass someObjects;
我宁可gc。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #64 (permalink)  
旧 2008-03-03
Elminster 的头像
超级版主
 
注册日期: 2002-09-09
帖子: 1,763
Elminster 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

说来说去还是这个“确定性”。sjinny 应该明确一下:

1. 这个“确定性”的定义是什么?是指内存释放时机能够由程序员手工指定么?
2. 为什么一定要有这个“确定性”?它究竟能带来什么好处?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #65 (permalink)  
旧 2008-03-04
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

我只是觉得sjinny太感性了。观点不清楚,推理也太主观,都不能自圆其说。看了半天,我只看出他不喜欢gc的内存回收的时机不确定,甚至不喜欢现代编译器的很多基本的优化操作,但是又除了“我觉得,我认为”提不出更有说服力的理由。

似乎研究最底层的汇编比较合适?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #66 (permalink)  
旧 2008-03-04
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

如果说寄存器的使用是非常贴近实现层面的,那么各种控制变量就相对贴近设计层面了。当我在某个花括号外时,我可以肯定这对括号内的东西不会对我有任何影响,并且我也不需要去关心里面的东西,如果没了这个花括号,那么我需要阅读更多的代码才能推测出这些信息。

我一直没对确定性定过概念,如果要定概念,那就是:程序员对所采用的技术的运行情况的了解程度(及了解的难易程度),这就是确定性。
虽然我们无法改变栈的行为,但是我们能够很容易的了解及预测栈的行为,并且栈的行为在代码里是显式表达的(用花括号对)。
确定性带来的好处,首先是我们能够比较容易的理解自己所写出的程序,而这又是程序的维护和复用的前提。并不是说gc完全无法使用,但是如果能用栈的情况下仍然使用gc,那么用花括号所表达的那些信息就丢失了,这对于以后的开发是不利的。

恩,我承认现在我的很对想法都很主观,所以才要来讨论嘛~ ^_^
但是在我看到其他人的文章或者帖子后,我才有了之前的种种想法。
很主观的说,不确定性对我来说就是个很有说服力的理由,如果我不知道我的工具的行为,我自然不敢用它,更何况它并没有人类的智慧。
至于编译器的优化,首先如果开启很高程度的优化,那么程序必须经过严密的测试才能确定这个优化不会带来负面影响,这是我在一些关于LSF的文章里看到的,所以现在的编译器优化还不能让人高枕无忧。另一方面,乱序执行对于多线程程序的开发的确会产生负面影响。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #67 (permalink)  
旧 2008-03-04
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,560
文章: 6
cat 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

如果只是说对象的生存期是否确定的话,和gc完全扯不上关系。
我的C#里面一大堆using生存期都很确定的,对于那些string之流他爱活多久我也管不着。
要解放思想~~

引用:
作者: sjinny
如果我不知道我的工具的行为,我自然不敢用它,更何况它并没有人类的智慧。
……
所以现在的编译器优化还不能让人高枕无忧。另一方面,乱序执行对于多线程程序的开发的确会产生负面影响。
你从前知道你的编译器在背后干了什么吗?知道CPU在里面做了什么手脚吗?知道OS的在背后又干了什么吗?知道Task Manager里面Physical Memory这一栏的System Cache都在干啥嘛?不知道编译优化多么猛,不知道乱序执行这回事,也不影响你对程序的理解吧?知道了反而觉得是洪水猛兽心理不安了,连编译器都觉得不能高枕无忧了。有个成语可以概括这个心理。

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

我是在了解到这些情况之后才开始杯弓蛇影的……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #69 (permalink)  
旧 2008-03-05
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
静态信息的确是不完全的,但是有些东西最好还是让程序员自己来说明。比如说栈,你可以根据代码进行静态分析,让程序自己得出结论某个变量有明确的作用域。可是那只是一种结果,却不能反应程序员的意图。如果像C这样显式地说明栈,那么说明的就是程序员的意图:我不想让栈里的这些变量的作用域泄露到栈外。栈相当于微观上的模块边界,如果这些都要让程序去检测、去猜测,那么显然就是让程序去决定微观模块边界了。如果需求不变,那么代码形成的事实上边界就是程序检测出的,以这个边界来组织目标代码是没问题的。但是如果需求会变呢?当代码写完之后过了一段不长不短的时间后,当人不记得程序的细节之后,一段代码里如果没有程序员给出的显式边界,那么如何理解程序中各种变量的意图?即使读代码的人能够看出代码里事实上的边界,但是按照原先的设计,设计意图中的边界却得不到体现,于是就只知道这个变量目前的生存期可以压缩到某个范围,却不知道在这个范围之外对它的使用是否符合原先的设计,而且如果使用了某个超出了设计中的边界的变量,那么这时编译器是无法检测出来的,于是编译器本来能够检测的错误就无法检测出来了。如果代码里不能承载设计信息,那么也许一时之间没有问题,但是当一段时间之后,人遗忘了设计信息之后,这段代码就变得难以维护了。任何程序,也许能够了解这段代码目前的情况,也许能用各种技术进行扫描和推断,但是这些技术无法从根本上理解需求,所以它们获得的信息同样是不完全的。也许人对代码的了解不如这些分析程序多,但是人对需求的了解绝对多于这些程序,其实我认为这些程序无法理解需求。一段代码,如果要复用它,那么就要知道使用它的前提条件,以及使用它时要为它提供什么样的环境,所以一段代码自身附带的设计信息越多,越容易让人理解它,那么就越容易复用。
说实话,我完全没看懂这段话。你能不能举个具体的例子来体现你想像的这个“问题”?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #70 (permalink)  
旧 2008-03-05
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

手边没有典型的例子。我这么说吧:
在C里,花括号是对生命期的一种表达符号,无论是函数的,还是if、for的,或者单独的花括号对,它们都表达了一种嵌套的生命期。
一个极端的例子:一个函数里的内部变量是不会泄露到外面的,所以使用这个函数时要关注的仅仅是它的接口。但是如果没有用花括号来说明那些内部变量的生命期,那么意味着它们是可能泄漏到函数外的。虽然在外界操纵函数的内部变量是不好的,但是在没有明确限制的情况下,一个设计不好的接口很可能就会把内部变量泄漏出去,特别是类的成员函数,这就破坏了封装性。而函数内部的花括号对,其实也是类似于函数的微观模块。


想了半天没想出什么例子,毕竟还没看过一点显式生命期控制/描述都没有的语言……

我那段话的意思只是说:应该赋予程序员尽量强大的表达工具,机器分析只是起弥补的作用。如果不要求程序员给出丰富的描述信息,然后再让程序来猜,那就不好了。
各种自动化技术是在帮助程序员,但是如果开始替代程序员,那就走向反面了。一直到现在,语言里仍然保留了goto。一直到现在C++也仍然保留了内嵌汇编的能力。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #71 (permalink)  
旧 2008-03-05
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

突然想起来,C++里,程序员可以在函数接口上描述可能抛出的异常,也可以完全不描述。
如果一个函数明确的用throw()表示自己不会抛出异常,那么当以后要维护这个函数时,就能明白以前的使用很可能是基于“它不会抛出异常”这个假设的,那么现在的修改就要维持这一约束。可是如果不把这个信息用throw()描述出来,那么虽然一开始编译的时候编译器能够分析出来这个函数不会抛出异常,但是编译器不可能知道,这到底只是一个偶然的事实结果,还是程序员刻意的设计。前者意味着以后的修改可以使它抛出异常,而如果是后者,那么意味着以后的修改是不能让它抛出异常的。自动化分析只能知道这个函数现在是否会抛出异常,但是不知道它以后是否也应该维持这种状态。这时如果程序员不加以描述,那么以后维护时就可能会引入bug。

总体的意思就是说,有些东西,编译器只能分析出当前的状态,但是分析不出,在人脑的设计之中程序应该是怎样的;自动分析程序无法区分一个结果是偶然的结果,还是应该一直维持的约束。如果不加以描述,一段时间之后,人也难以分析清楚。
所以在程序中,给予程序员以丰富的表达手段,把设计信息在代码中表达出来,这比过度依赖自动化分析更好。


虽然不是针对栈的,但是大致能表达我的意思了。汗。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #72 (permalink)  
旧 2008-03-05
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
手边没有典型的例子。我这么说吧:
在C里,花括号是对生命期的一种表达符号,无论是函数的,还是if、for的,或者单独的花括号对,它们都表达了一种嵌套的生命期。
一个极端的例子:一个函数里的内部变量是不会泄露到外面的,所以使用这个函数时要关注的仅仅是它的接口。但是如果没有用花括号来说明那些内部变量的生命期,那么意味着它们是可能泄漏到函数外的。虽然在外界操纵函数的内部变量是不好的,但是在没有明确限制的情况下,一个设计不好的接口很可能就会把内部变量泄漏出去,特别是类的成员函数,这就破坏了封装性。而函数内部的花括号对,其实也是类似于函数的微观模块。


想了半天没想出什么例子,毕竟还没看过一点显式生命期控制/描述都没有的语言……

我那段话的意思只是说:应该赋予程序员尽量强大的表达工具,机器分析只是起弥补的作用。如果不要求程序员给出丰富的描述信息,然后再让程序来猜,那就不好了。
各种自动化技术是在帮助程序员,但是如果开始替代程序员,那就走向反面了。一直到现在,语言里仍然保留了goto。一直到现在C++也仍然保留了内嵌汇编的能力。
你觉得下面的c代码中,i这个栈变量一定是在花括号结束的地方才失效的?
代码:
{ int i = 1; int j = i; cout << j; }
不熟悉寄存器分配算法吧?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #73 (permalink)  
旧 2008-03-05
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

有一句话,叫做abstract is selective ignorance,我觉得很有道理。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #74 (permalink)  
旧 2008-03-05
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

呃……如果不是花括号的时候失效,那么是什么时候呢?如果涉及到编译器的优化,那当我没问……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #75 (permalink)  
旧 2008-03-06
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

1。谁也没保证过i和j就一定会在栈上分配。编译器完全可以把它们放在寄存器里。
2。谁也没保证过i和j肯定占用各自独立的寄存器或者栈空间,编译器完全可以经过分析发现j使用的时候i已经用不着了,所以干脆节省了一个寄存器/栈空间和一次赋值操作。
3。甚至没有保证会分配任何寄存器/栈空间,编译器完全可以直接把常量1编进机器码,就根本不会出现所谓“局部变量”。
4。所有这些都跟程序员没关系,你关心的就是cout能打印出来那个值。其它的什么“意图”什么的扯不上。

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

本质上说,你写程序是为了表达你的意图。也就是说,程序是你逻辑的体现。
如果我写一个printf都要考虑流水线的更新情况,那么我写不了任何程序的。为什么现在的程序比上世纪50-60年代的要大?除了方法论/硬件的进步以外,还因为现在的开发环境让程序员可以更为专心地考虑解决方案,而不是和领域外的问题纠缠。
我也建议你提出一个具体的例子,然后说出为什么使用目前的GC+using结构不能满足你的要求。很多时候,你觉得有个问题很大,但是有没有确定的例子,很可能是因为这个问题本身不是问题。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #77 (permalink)  
旧 2008-03-06
sjinny 的头像
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

我还没有足够的经验,不过根据我目前的了解,我对某些技术持比较保守的态度。
不过,不管编译器怎么优化,花括号里的那些变量是不会泄露到外面去的。至少在编写代码时是可以这么认为的吧。

此帖于 2008-03-06 01:36 PM 被 sjinny 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #78 (permalink)  
旧 2008-03-06
Elminster 的头像
超级版主
 
注册日期: 2002-09-09
帖子: 1,763
Elminster 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
我还没有足够的经验,不过根据我目前的了解,我对某些技术持比较保守的态度。
不过,不管编译器怎么优化,花括号里的那些变量是不会泄露到外面去的。至少在编写代码时是可以这么认为的吧。
这个还真不一定,用 C++ 的应该知道 RVO 吧?你想想看这算不算把一个“被程序员写在一对花括号里”的对象,移到了花括号之外。

引用:
作者: sjinny
我一直没对确定性定过概念,如果要定概念,那就是:程序员对所采用的技术的运行情况的了解程度(及了解的难易程度),这就是确定性。
虽然我们无法改变栈的行为,但是我们能够很容易的了解及预测栈的行为,并且栈的行为在代码里是显式表达的(用花括号对)。
确定性带来的好处,首先是我们能够比较容易的理解自己所写出的程序,而这又是程序的维护和复用的前提。并不是说gc完全无法使用,但是如果能用栈的情况下仍然使用gc,那么用花括号所表达的那些信息就丢失了,这对于以后的开发是不利的。
你这个确定性的概念倒是有趣。不过要说容易理解和预测程序的行为,其实用 GC 的更有优势。为啥呢?因为有了 GC 的支持,书写程序的时候可以广泛地使用引用语义,简单地说就是一个函数在接受一个对象作为参数或是返回一个对象的时候,实际上是在接受和返回一个指向对象的指针。这样做可以避开拷贝构造的问题,程序的行为要简单而且容易预测得多了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #79 (permalink)  
旧 2008-03-06
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: sjinny 查看帖子
我还没有足够的经验,不过根据我目前的了解,我对某些技术持比较保守的态度。
不过,不管编译器怎么优化,花括号里的那些变量是不会泄露到外面去的。至少在编写代码时是可以这么认为的吧。
看你怎么定义“泄露”了。如果说不会在花括号结束后被外界感知,用gc也不会:
代码:
{ Integer i = new Integer(1); Integer j = i; System.out.println(i); }
实际上,用c的话,反而可能被外界感知:
代码:
int* p; { int i = 1; p = &i; }
而如果定义为它占用的空间必然确定性地在花括号结束的瞬间回收的话,那么即使c/c++也不这么保证的。编译器完全有自由等到函数退出再清理堆栈。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #80 (permalink)  
旧 2008-03-06
高级会员
 
注册日期: 2002-09-15
帖子: 2,531
ajoo 正向着好的方向发展
默认 回复: 请教各位大大关于动态内存管理的问题……

引用:
作者: Elminster 查看帖子
这个还真不一定,用 C++ 的应该知道 RVO 吧?你想想看这算不算把一个“被程序员写在一对花括号里”的对象,移到了花括号之外。
rvo我倒真认为是对语义的破坏。原本我可以指望我的~Microsoft()里面的cout<<"打倒死胖子!"在函数结束的地方执行的,结果你一rvo,得,正义得不到伸张了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

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

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