免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1011 | 回复: 0
打印 上一主题 下一主题

内存管理之引用计数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:44 |只看该作者 |倒序浏览

一、什么是引用计数?
   
引用计数是内存管理的一个技巧,可以看做是一种简单的垃圾回收机制,它允许多个拥有共同值的对象共享同一个对象。

二、为什么采用它?
   
对于没有垃圾自动回收机制的语言(如C/C++)和技术(如COM)来说,引用计数提供了一种简洁高效的内存管理方法。
  • 它简化了跟踪处理堆中对象的过程
     
 一个对象被从堆中分配出来之后,我们需要明确的知道是谁拥有了这个对象,因为只有拥有这个对象的所有者能够销毁它。但我们在实际使用过程中, 这个对象可能被传递给另一个对象(例如通过传递指针参数),一旦这个过程复杂,我们很难确定谁最后拥有了这个对象。
     使用引用计数就可以抛开这个问题,我们不需要再去关心谁拥有了这个对象,因为我们把管理权交割给了对象自己(这有点类似__stdcall和__cdecl两种函数调用约定)。当这个对象不再被任何人使用时,它自己负责销毁自己。
  • 简单并且高效
     
简单是特定时候增减一下对象的引用计数就可以了。高效是让多个具有相同值的对象共享同一个对象,省却了拷贝复值的过程,而且更加节省内存和宝贵的CPU时间。

三、谁都在使用它?
   
现在很多技术和编程语言都在使用它,如COM,Object-C等,如果我们愿意,我们可以在自己的程序中使用它。
  • COM
    
IUnknow提供了三个接口:QueryInterface、AddRef、Release。后面两个分别用来增减和减少通过QueryInterface获取的接口对象的引用计数,当内部的计数为0时,接口对象自动销毁自身。
  • COM的宿主DLL
    
这种类型的DLL包含四个导出函数:DLLRegisterServer、DLLUnregisterServer、DLLGetClassObject、DLLCanUnloadNoew。最后一个函数就是通过查看DLL维护的组件的计数值来决定这个DLL是否可以被CoFreeUnusedLibraries卸载掉。
  • Object-C
    
Object-C作为C的派生语言,它的内存管理彻底的采用了这个技巧。它的Foundation框架提供了是哪个方法:autoreleae、retain、release。第一个是将一个对象交由自动释放池管理,其实是自动调用了release;后面两个和COM中的最后两个是相同的,分别用来增加和减少引用计数。

四、我该如何实现它?
   
下面我给出一个很简单的例子,演示如何实现引用计数。
  
class Foo{
public:
    Foo(){
        _ref 
= 1;//构造成功之后计数即为1
    }
    
//辅助,用来打印引用计数
    void Print(){  
        std::cout 
<< "_ref = " << _ref << std::endl;
    }
public:
    
//增加引用计数
    ULONG AddRef(){
        
return InterlockedIncrement(&_ref);
    }
    
//减少引用计数
    ULONG Release(){
        
if (0 == InterlockedDecrement(&_ref)){
            delete 
this;
            
return 0;
        }
        
return _ref;
    }
private:
    
long _ref;
};

int main(int argc, char *argv[])
{
    Foo 
* foo = new Foo;
    foo
->Print();//输出:_ref = 1
    foo->Release();
    foo
->Print();//输出:_ref = 随机数字

    
return 0;
}

PS: 这里是云风写的一篇文章《引用计数与垃圾回收之比较》,我认为写的非常好。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP