其中的AddRef和Release是用来让组件自己管理其生命周期,而客户程序只关心接口,而无须再去关心组件的生命周期,一个简单的使用示例如下:

 

int main()
{
    IUnknown* pi = CreateInstance();
 
    IX* pix = NULL;
    HRESULT hr = pi->QueryInterface(IID_IX, (void*)&pix);
    if(SUCCEEDED(hr))
    {
        pix->DoSomething();
        pix->Release();
    }
 
    pi->Release();
}
 

  上面的客户程序在CreateInstance中已经调用过AddRef,所以无需再次调用,而在使用完接口后调用Release,这样组件自己维护的计数值将会改变。下面代码给出一个简单的实现AddRef和Release示例:

 

 

ULONG _stdcall AddRef()
{
    return ++ m_cRef;
}
 
ULONG _stdcall Release()
{
    if(--m_cRef == 0)
    {
        delete this;
        return 0;
    }
    return m_cRef;

 

  在编程语言Python中,使用也是引用计数算法,当对象的引用计数值为0时,将会调用__del__函数,至于为什么Python要选用引用计数算法,据我看过的一篇文章里面说,由于Python作为脚本语言,经常要与C/C++这些语言交互,而使用引用计数算法可以避免改变对象在内存中的位置,而Python为了解决环形引用问题,也引入gc模块,所以本质上Python的GC的方案是混合引用计数和跟踪(后面要讲的三个算法)两种垃圾回收机制。

2.标记-清除算法

  标记-清除(Mark-Sweep)算法依赖于对所有存活对象进行一次全局遍历来确定哪些对象可以回收,遍历的过程从根出发,找到所有可达对象,除此之外,其它不可达的对象是垃圾对象,可被回收。整个过程分为两个阶段:标记阶段找到所有存活对象;清除阶段清除所有垃圾对象。