`
cppmule
  • 浏览: 436538 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

内存管理之引用计数

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

二、为什么采用它?
   对于没有垃圾自动回收机制的语言(如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: 这里是云风写的一篇文章《引用计数与垃圾回收之比较》,我认为写的非常好。
分享到:
评论

相关推荐

    ios5之自动引用计数

    ios5的内存管理引入自动引用计数,本资料进行了详细说明和介绍,供有需要的人下载使用。

    OC中的内存管理

    OC内存管理:采用引用计数的方式管理内存 MRC :手动管理内存(手动管理引用计数) ARC:自动管理内存(自动管理引用计数)--系统默认

    iOS内存管理中引用计数的学习

    给大家分享了关于iOS内存管理中引用计数的相关知识点,对此有需要的朋友可以跟着学习下。

    内存管理内存管理内存管理

    内存管理是计算机编程最为基本的领域之一。在很多脚本语言中,您不必担心内存是如何管理的,这并不能使得内存管理的重要性有一点点降低。对实际编程来说,理解您的内存管理器的能力与局限性至关重要。在大部分系统...

    操作系统(内存管理)

    内存管理是计算机编程最为基本的领域之一。在很多脚本语言中,您不必担心内存是如何管理的,这并不能使得内存管理的重要性有一点点降低。对实际编程来说,理解您的内存管理器的能力与局限性至关重要。在大部分系统...

    Python引用计数操作示例

    为了简化内存管理,Python通过引用计数机制实现了自动的垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁...

    python内存管理机制原理详解

    当对象引用计数等于 0 时, 对象被删除(引用计数是一种非常高效的内存管理机制) 2. 垃圾回收 垃圾回收机制: ① 引用计数 , ②标记清除 , ③分带回收 引用计数 : 引用计数也是一种垃圾收集机制, 而且也是一种最直观...

    详谈swift内存管理中的引用计数

    下面小编就为大家带来一篇详谈swift内存管理中的引用计数。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    iOS 内存管理机制 详细解读

    5.1)Objective-C内存管理相关术语 5.2)什么是引用计数? 5.2.1)引用计数解释 5.2.2)文艺解释 5.2.3)代码测试 5.3)自动释放池 5.3.1)AutoreleasePool的原理 5.3.2)自动释放池的创建和销毁 5.3.3)自动释放池的使用...

    luarc-5.1:Lua5.1的引用计数版本

    #Luarc-5.1 在 Lua 5.1.4 中实现的引用计数内存管理和 Mark/Sweep GC 的实现。 #执行使用纯引用计数实现,即一旦引用计数变为 0,堆对象将被回收,不使用延迟释放。 是的,由于引用计数更新,更多的cpu周期用于参数...

    Swift编程中用以管理内存的自动引用计数详解

    主要介绍了Swift编程中用以管理内存的自动引用计数详解,是Swift入门学习中的基础知识,需要的朋友可以参考下

    Swift 自动引用计数(ARC).pdf

    Swift 使用自动引用计数(ARC)这一机制来跟踪和管理应用程序的内存 通常情况下我们不需要去手动释放内存,因为 ARC 会在类的实例不再被使用时,自动释放其占用的内存。 但在有些时候我们还是需要在代码中实现内存...

    Object C 内存管理

    Object C 内存管理课件,关于一些内存管理机制 还有手动内存 引用计数操作的一些 小例子

    iOS内存管理1

    iOS内存管理暴风体育 分享 iOS引用计数查看引用计数:MRC: [object retainCount]强引用/弱引用普通指针: void *强引用:类似B

    python的内存管理和垃圾回收机制详解

    引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用时其引用计数增加1,当其不再被引用时引用计数减1,当引用计数等于0的时候,对象就被删除了。 2,垃圾回收(这是一个很重要知识点): ① 引用计数 ...

    python面试题及答案.pdf

    1. Python是如何进行内存管理的? 答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制 一、对象的引用计数机制 python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。 引用...

    python 怎样进行内存管理

    从三个方面来说,主要有方面的措施:对象的引用计数机制、垃圾回收机制、内存池机制。 一、对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。 引用计数增加的情况: 1、...

    python笔记题带答案.doc

    1.Python是如何进行内存管理的? 答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制 一、对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。 引用计数...

    objective-c启用ARC时的内存管理

    在objective-c中,内存的引用计数一直是一个让人比较头疼的问题。尤其是当引用计数涉及到arc、blocks等等的时候。似乎ARC的出现只是让我们解放了双手,由于底层实现依然依赖引用计数,所以开启ARC后,只有对引用计数...

Global site tag (gtag.js) - Google Analytics