CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  模式及实现

计数指针 (Counter Pointer) 与 垃圾回收器 (Garbage Collection) 有何分别?

楼主gameboy007(WoHaHa-WaHaHaHaHa)2006-11-21 09:36:38 在 C/C++ / 模式及实现 提问

小弟一向都使用CounterPointer来处理调用new所产生的指针,一向都没有什麽问题,  
  所以不觉得须要有垃圾回收器的必要,我不知自己认知的是否正确,  
  牛哥们可以讨论一下   Counter   Pointer   与   Garbage   Collection   的分别在那里吗?  
  问题点数:100、回复次数:25Top

1 楼steedhorse(晨星)回复于 2006-11-21 09:43:02 得分 0

现在许多高效的GC都不采用CP机制了。Top

2 楼steedhorse(晨星)回复于 2006-11-21 09:45:48 得分 0

如果手工进行referrence   counter,至少对程序员不透明,而GC对程序员完全是透明,程序员想用资源时尽管申请,别的啥也不用管。  
  当然,开发效率(甚至某种程度上的运行效率)的提高是以运行时空间占用为代价的。Top

3 楼Polarislee(北极星)(无房无车,飘在北京)回复于 2006-11-21 12:58:39 得分 0

Reference   Counter有几个最致命的缺陷  
   
  1.   无法释放有循环引用对象。  
  2.   在进行对象遍历的时候十分影响效率  
  3.   在多线程共享对象时,需要十分注意处理竞争条件Top

4 楼OnlyHappy(说好不打脸)回复于 2006-11-21 13:02:16 得分 0

还是C爽。。Mark   一把Top

5 楼Polarislee(北极星)(无房无车,飘在北京)回复于 2006-11-21 13:03:36 得分 0

至于GC的实现方式有很多,细节可以写一本书(的确有这样一本书可以买到)  
   
  常用的GC算法可以释放循环引用,不会影响对象操作的效率,而且实现线程安全的(实际上GC的时候会暂停正在处理的线程)。  
   
  但是通常GC会导致程序的相应性能下降,而且GC的很多行为是不能预测的,不利于在实时系统中的应用。Top

6 楼Polarislee(北极星)(无房无车,飘在北京)回复于 2006-11-21 13:07:24 得分 0

从OnlyHappy的话来看,总感觉C/C++的程序员对GC有一种天然的抗拒心理,其实大可不必。无论是手动管理,智能指针还是GC不过都是内存管理的方式而已。各有各的优缺点和适应性。  
   
  不可否认,在绝大多数情况下,GC可以极大地减轻developer的负担,提高开发效率并减少错误。Top

7 楼OnlyHappy(说好不打脸)回复于 2006-11-21 13:14:47 得分 0

>>不可否认,在绝大多数情况下,GC可以极大地减轻developer的负担,提高开发效率并减少错?>>误。  
  是的。能提高开发效率,但是作了包装后,总觉得不透明,别人做GC功能肯定要考虑到很多方面的东西。其实有很多情况下并不要多线程什么的。这个就有点浪费了。。。。Top

8 楼steedhorse(晨星)回复于 2006-11-21 13:27:01 得分 0

//其实有很多情况下并不要多线程什么的。这个就有点浪费了。。。。  
  ——“不要多线程”跟“不要GC”并没有什么直接联系或因果关系啊。Top

9 楼owlling(owlman)回复于 2006-11-21 13:33:39 得分 0

只能说指针计数可能是GC的一种手段而已,而且现在来看这种手段并不怎么有效、  
  另外,多线程和gc更不说不到一起去。他们各自属于的内存管理层次都是不同的。。Top

10 楼gameboy007(WoHaHa-WaHaHaHaHa)回复于 2006-11-21 16:20:37 得分 0

>>   steedhorse(晨星)   :  
  >>   现在许多高效的GC都不采用CP机制了。  
   
  如果GC不用Counter来记下有多少个地方使用这个指针,  
  那麽又可以用什麽方法?我想GC总得也要释放没有使用  
  的指针吧,当中不用counter机制还可以用什麽呢?  
   
  >>   如果手工进行reference   counter,至少对程序员不透明,而GC对程序员完全是透明...  
   
  不明白"手工进行reference   counter"的意思,但我也有一个感觉,就是当一个CounterPointer  
  被多个地方同时使用时,的确有那种不透明的感觉。  
  那麽可否描述一下GC是如何提供透明度?  
   
   
   
  >>   Polarislee(北极星):  
  >>   1.   无法释放有循环引用对象  
   
  我想这真是致命的缺陷,虽然循环引用的机会非常少见,当这种事情发生  
  也是代表了程式设计出问题。  
   
  >>   2.   在进行对象遍历的时候十分影响效率  
   
  这点我听不懂,可以说多点吗?  
   
   
   
  >>   OnlyHappy(说好不打脸)   :  
  >>   还是C爽  
   
  我不太认同这种说法,我开发C程序多年,如果是写一个小程式,C真的很爽,但开发大型程式  
  时我没有见过C程序员是爽的,这也是我们公司在4年前全面转用C++的原因,我的经验是在小型  
  程式中C是C++代码的70%,一但开发大型程式,C代码多出C++代码2至3倍!还爽吗?  
  当然这只是小弟个人的经验,或者我的C程序写得差吧。:   )  
   
  Top

11 楼steedhorse(晨星)回复于 2006-11-22 13:01:23 得分 0

To:gameboy007(WoHaHa-WaHaHaHaHa)  
  我不知道北极星说的那本专讲GC实现的书是哪本。你可以问问他,买来看看。  
   
  但我知道《Programming   Microsoft   .net   Framework   Applications》(好像是这个名字),讲到了.net平台上GC的实现,虽然不算特别详尽,但至少可以让人明白个大概。你可以买来看看。:)  
   
  另外,《Inside   Java   Virtual   Machine》一书应该也可以买来看看。Top

12 楼mLee79()回复于 2006-11-22 15:14:57 得分 0

GC   通常可以这样实现   ...  
  *   标记-清除,   让所有的活动的对象自己做一个标记,   最后没有做标记的对象被清除   ...  
  *   想想自己在整理物品的时候怎么做的就知道了,   把有用的东西放在个新的地方,   剩下的就被回收   ....  
  基于   cp   的很难有一个通用的高效的机制实现,   貌似历史上就基本上没被使用过,   不过对些特定的数据类型是最高效的,   不过感觉上不算是   gc   ...  
   
  实际上,   c   里用   gc   方便多了,   一般人我还不告诉他   ...  
  Top

13 楼chengyimin()回复于 2006-11-23 21:26:18 得分 0

请问楼上的,标记-清除怎么环形应用的?  
  一直想不通...Top

14 楼steedhorse(晨星)回复于 2006-11-23 21:36:34 得分 0

标记-清除法,对于没有用了的对象,既使它里边有环,也根本标记不到了,所以干粹就统统扔了。Top

15 楼FantasyNES()回复于 2006-11-24 17:11:59 得分 0

http://www.china-pub.com/computers/common/info.asp?id=18468  
   
  这本专门讲gc的,说的不错Top

16 楼gameboy007(WoHaHa-WaHaHaHaHa)回复于 2006-11-24 19:49:17 得分 0

谢谢!   steedhorse(晨星)   ,   FantasyNES()     提供的  
  Programming   Microsoft   .net   Framework   Applications  
  Inside   Java   Virtual   Machine  
  http://www.china-pub.com/computers/common/info.asp?id=18468   (垃圾回收)  
   
  我去书店一定会留意这三本书!  
   
   
  >>   mLee79()      
  >>   实际上,   c   里用   gc   方便多了,   一般人我还不告诉他   ...  
   
  C如可实现垃圾回收?垃圾回收代表了一种自动化,但C是必须要调用函数才能  
  工作的,那麽如何在离开scope时自动回收垃圾呢,C是没有destructor这东西的,  
  是否须要多线程才能做到?有没有一些例子?Top

17 楼owlling(owlman)回复于 2006-11-24 19:52:19 得分 0

随便提下。现在的gc和图论倒是有很多联系的,呵呵,,,Top

18 楼mLee79()回复于 2006-11-24 21:35:50 得分 0

我通常的认为   gc   是一种资源管理的思想,   而不仅仅是程序员偷懒的手段,   在   C   中使用   gc   基本上可以做到除了在内存不足的时候所发生的gc之外对程序员将是透明的,   对性能的影响也将相当的小   ,     C   是用于系统编程的,   显然不可能假定运行于多任务多线程的环境,   当然在多线程环境下也可以起一个   idle   线程专门做   gc   工作,   不过感觉上没啥必要   ...  
   
  大概就做成这个样子   :  
  foobar()  
  {  
  int   *buff1   ,   *buff2;  
  __GC_CTX_push();  
  buff1   =   __GC_malloc(   100   ,   __GC_TEMP_BUFF   |   __GC_POD     );  
  buff2   =   __GC_malloc(   100   ,   __GC_PREV_CTX     |   __GC_POD     );    
  $use(   buff1   ,   buff2   ,   pInt   ,   pStrArr   ,   pObj   ,   pObj2   );  
  __GC_CTX_pop(); //   buff1   被   gc   回收   ,   buff2   要直到下一次   __GC_RETURN   ,   __GC_CTX_pop   才参加   gc   ..  
  }  
  foo1()  
  {  
  int         *   pInt;  
  __X_string   *   pStrArr;  
  __X_Object   *   pObj   ,   *   pObj2;  
   
  __GC_ENV_INIT;  
  pInt         =   __GC_malloc(   1024   *   sizeof(   int   )   ,     __GC_TEMP_BUFF   |   __GC_POD   );  
  pStrArr   =   __GC_malloc(   100   *   sizeof(   __X_string   )   ,   __GC_CURR_CTX   |   __GC_BY_REF_COUNT   ,   __X_string_destroy     );  
  pObj         =   __GC_malloc(   sizeof(   __X_Object   )   ,   __GC_CURR_CTX     |   __GC_OBJECT   ,     __X_Object_destroy   ,   __X_Object_mark   );  
  pObj2       =   __GC_malloc(   sizeof(   __YY_Object   )   ,   __GC_CURR_CTX   |   __GC_OBJECT_VTBL   ,   __YY_Object_vtbl   );  
  foobar(   pInt   ,   pStrArr   ,   pObj   ,   pObj2   );  
  if(   xxx   )  
  __GC_RETURN(   FAILED   );  
    __GC_RETURN(   SUCCESS   );   //   pInt,   foobar.buff2   被   gc   回收   .....  
  }  
  runFunc1()  
  {  
  __GC_CTX_push();  
  foo1();  
  __GC_CTX_pop(); //   pStrArr   ,   pObj   ,   pObj2   参加   gc   ....  
  }  
  appEntry   ()  
  {  
  __GC_CTX_new();  
                  runFunc1();  
  __GC_CTX_destroy();  
  }  
   
  Top

19 楼gameboy007(WoHaHa-WaHaHaHaHa)回复于 2006-11-25 20:12:01 得分 0

谢谢   mLee79()   的   C   的   GC   程式段落,虽然看了C的GC实验,但个人觉得  
  C要废这麽大段程式码才做了这麽少。这也是C得短点,在每离开scope  
  时都要调用   __GC_CTX_pop()   这点上就不显得自动化和优雅了,但这也是没  
  办法,用C就是要有这种不怕苦的性格。  
  我看出虽然C实现GC需要的程式码比C++多得多,但在背後也显出C程式码  
  一板一眼,比C++少了好多看不出的缺陷。  
   
   
  >>   我通常的认为   gc   是一种资源管理的思想,   而不仅仅是程序员偷懒的手段,   .....  
  另外非常同意   mLee79()   说的以上那段话!  
   
   
  我觉得每个C/C++程序员都需要有实现资源管理这种能力,因为在整个  
  程序中只有不多过10%的程式码是要最优化的,还有C/C++本身的速度就很快,  
  没有必要在所有的程式段中都需要原始指针,所以我觉得C/C++程序应该大量  
  使用Counter   Pointer、Smart   Pointer或者Garbage   Collection来减少程序负担。Top

20 楼FantasyNES()回复于 2006-11-26 09:15:42 得分 0

mame里面也实现了一个类似gc的东西,不过简单多了  
   
  /***************************************************************************  
   
          Resource   tracking   code  
   
  ***************************************************************************/  
   
  /*-------------------------------------------------  
          auto_malloc_add   -   add   pointer   to   malloc   list  
  -------------------------------------------------*/  
   
  INLINE   void   auto_malloc_add(void   *result)  
  {  
  /*   make   sure   we   have   tracking   space   */  
  if   (malloc_list_index   ==   malloc_list_size)  
  {  
  void   **list;  
   
  /*   if   this   is   the   first   time,   allocate   256   entries,   otherwise   double   the   slots   */  
  if   (malloc_list_size   ==   0)  
  malloc_list_size   =   256;  
  else  
  malloc_list_size   *=   2;  
   
  /*   realloc   the   list   */  
  list   =   realloc(malloc_list,   malloc_list_size   *   sizeof(list[0]));  
  if   (list   ==   NULL)  
  fatalerror("Unable   to   extend   malloc   tracking   array   to   %d   slots",   malloc_list_size);  
  malloc_list   =   list;  
  }  
  malloc_list[malloc_list_index++]   =   result;  
  }  
   
   
  /*-------------------------------------------------  
          auto_malloc_free   -   release   auto_malloc'd   memory  
  -------------------------------------------------*/  
   
  static   void   auto_malloc_free(void)  
  {  
  /*   start   at   the   end   and   free   everything   till   you   reach   the   sentinel   */  
  while   (malloc_list_index   >   0   &&   malloc_list[--malloc_list_index]   !=   NULL)  
  free(malloc_list[malloc_list_index]);  
   
  /*   if   we   free   everything,   free   the   list   */  
  if   (malloc_list_index   ==   0)  
  {  
  free(malloc_list);  
  malloc_list   =   NULL;  
  malloc_list_size   =   0;  
  }  
  }  
   
   
  /*-------------------------------------------------  
          begin_resource_tracking   -   start   tracking  
          resources  
  -------------------------------------------------*/  
   
  void   begin_resource_tracking(void)  
  {  
  /*   add   a   NULL   as   a   sentinel   */  
  auto_malloc_add(NULL);  
   
  /*   increment   the   tag   counter   */  
  resource_tracking_tag++;  
  }  
   
   
  /*-------------------------------------------------  
          end_resource_tracking   -   stop   tracking  
          resources  
  -------------------------------------------------*/  
   
  void   end_resource_tracking(void)  
  {  
  /*   call   everyone   who   tracks   resources   to   let   them   know   */  
  auto_malloc_free();  
  timer_free();  
  state_save_free();  
   
  /*   decrement   the   tag   counter   */  
  resource_tracking_tag--;  
  }  
   
   
  /*-------------------------------------------------  
          auto_malloc   -   allocate   auto-freeing   memory  
  -------------------------------------------------*/  
   
  void   *_auto_malloc(size_t   size,   const   char   *file,   int   line)  
  {  
  void   *result;  
   
  /*   fail   horribly   if   it   doesn't   work   */  
  result   =   _malloc_or_die(size,   file,   line);  
   
  /*   track   this   item   in   our   list   */  
  auto_malloc_add(result);  
  return   result;  
  }  
   
   
  /*-------------------------------------------------  
          auto_strdup   -   allocate   auto-freeing   string  
  -------------------------------------------------*/  
   
  char   *auto_strdup(const   char   *str)  
  {  
  return   strcpy(auto_malloc(strlen(str)   +   1),   str);  
  }Top

21 楼gameboy007(WoHaHa-WaHaHaHaHa)回复于 2006-11-27 13:02:12 得分 0

谢谢FantasyNES()   提供MAME的GC  
   
  由MAME这段GC程式码可以看出C与C++的根本不同,经由_auto_malloc   的调用提  
  取指针,而在_auto_malloc背後调用auto_malloc_free登记这个指针,当程序员认为  
  不再需要时调用auto_malloc_free把整个malloc_list   free了。  
  但这存在一个问题,就是在begin_resource_tracking与end_resource_tracking之间  
  的程序中指针复制问题,就是说在某个或多个地方也正在使用这个指针时,  
  如果调用end_resource_tracking就会杀了这些正在某处使用的指针,即是说我们要在  
  任何时间都要记住有没有其他指针同时使用这个所为的   resource   pointer才可调用  
  end_resource_tracking。  
   
  当然我觉得这是可以改善的,就是每当复制一个resource   pointer时都调用一个好像  
  这样的一个函数:  
   
      int*   b   =   copy_resource_pointer(   a   );     <--   函数背後进行一些计数工作  
   
  当不要这个指针时就须要一个像这样的函数  
   
      despose_pointer(   b   );     <--     函数背後把这个已登记的指针counter减一  
   
  在GC这点上C++与C存有明显分别,C++有Constructor、Destructor和Copy   Constructor,  
  当我们产生一个Object复制Object或当Object离开scope时,constructor、copy   constructor  
  和Destructor会在我们背後自动完成它们应该的任务,这就型成一种自动化,在GC上更能  
  打做出优雅的程式码与行为,所以小弟觉得C++实现GC比C好一点。  
  不知小弟看法有否错误,大家有何意见?Top

22 楼DrawText(hDC,"阅尽A片,心中无码,戒手淫!",14,lpRect,DT_TOP)回复于 2006-12-22 22:52:32 得分 0

学到不少!Top

23 楼ReverseEngineering(★给我一杯壮阳水☆换我一夜不下垂★男人阳萎不是罪☆)回复于 2006-12-23 20:01:00 得分 0

学习!Top

24 楼rulary(秦枫)回复于 2007-01-18 11:25:06 得分 0

 
   
  收藏Top

25 楼classpatterns(一个2007毕业的小菜菜<闭关修炼ing>)回复于 2007-01-30 15:51:12 得分 0

xuexi...Top

相关问题

关键词

得分解答快速导航

  • 帖主:gameboy007

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo