Android -- sp、wp强弱指针的原理简介


我们知道,Android的native层代码基本都是C/C++的天下;基于这种特点,在native层中大量使用指针来操作对象就在所难免了。由于C/C++需要程序员手动操作管理内存,这就使程序出现内存管理问题的概率大大提高。所以,在Android中就提出了一种新的指针概念:强指针(sp)、弱指针(wp)来代替普通的指针;这种指针基于引用计数,来智能地管理对象指针,并不需要程序员做过多的内存管理操作。

在Android中,为了使用sp、wp,我们设计的类都必须是一个类的子类,那就是RefBase,我们看它的类定义:

//sp和wp已经深入融合到了Android系统native代码中,如果我们想使一个类型支持sp和wp操作,就必须
//让这个类继承RefBase类;从某一个角度来说,RefBase类很类似于Java中的Object类,因为它是所有native类的父类
class RefBase
{
public:
            void            incStrong(const void* id) const;//强引用计数方法
            void            decStrong(const void* id) const;//强引用计数方法
    
            void            forceIncStrong(const void* id) const;

            //! DEBUGGING ONLY: Get current strong ref count.
            int32_t         getStrongCount() const;

	//RefBase的一个内部类型,它是管理引用计数的一个重要辅助类
    class weakref_type
    {
    public:
        RefBase*            refBase() const;
        
        void                incWeak(const void* id);//弱引用计数方法
        void                decWeak(const void* id);//弱引用计数方法
        
        // acquires a strong reference if there is already one.
        bool                attemptIncStrong(const void* id);
        
        // acquires a weak reference if there is already one.
        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
        // for proper use.
        bool                attemptIncWeak(const void* id);

        //! DEBUGGING ONLY: Get current weak ref count.
        int32_t             getWeakCount() const;

        //! DEBUGGING ONLY: Print references held on object.
        void                printRefs() const;

        //! DEBUGGING ONLY: Enable tracking for this object.
        // enable -- enable/disable tracking
        // retain -- when tracking is enable, if true, then we save a stack trace
        //           for each reference and dereference; when retain == false, we
        //           match up references and dereferences and keep only the 
        //           outstanding ones.
        
        void                trackMe(bool enable, bool retain);
    };
    
            weakref_type*   createWeak(const void* id) const;
            
            weakref_type*   getWeakRefs() const;

            //! DEBUGGING ONLY: Print references held on object.
    inline  void            printRefs() const { getWeakRefs()->printRefs(); }

            //! DEBUGGING ONLY: Enable tracking of object.
    inline  void            trackMe(bool enable, bool retain)
    { 
        getWeakRefs()->trackMe(enable, retain); 
    }

    typedef RefBase basetype;

protected:
                            RefBase();
    virtual                 ~RefBase();
    
    //! Flags for extendObjectLifetime()
    enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };
    
            void            extendObjectLifetime(int32_t mode);
            
    //! Flags for onIncStrongAttempted()
    enum {
        FIRST_INC_STRONG = 0x0001
    };
    
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    virtual void            onLastWeakRef(const void* id);

private:
    friend class weakref_type;
    class weakref_impl;
    
                            RefBase(const RefBase& o);
            RefBase&        operator=(const RefBase& o);

private:
    friend class ReferenceMover;

    static void renameRefs(size_t n, const ReferenceRenamer& renamer);

    static void renameRefId(weakref_type* ref,
            const void* old_id, const void* new_id);

    static void renameRefId(RefBase* ref,
            const void* old_id, const void* new_id);

        weakref_impl* const mRefs;//用于引用计数
};

类中声明的inc、dec前缀的方法,就是用于操控引用计数的方法,某个指针的引用计数的状态就觉得了它自身的生命周期:何时被回收。

sp、wp虽然叫做强弱指针,但它们实际都是一个模板类,分别看它们的声明:

template <typename T>
class wp
{
public:
    typedef typename RefBase::weakref_type weakref_type;
    
    inline wp() : m_ptr(0) { }

    wp(T* other);
    wp(const wp<T>& other);
    wp(const sp<T>& other);
    template<typename U> wp(U* other);
    template<typename U> wp(const sp<U>& other);
    template<typename U> wp(const wp<U>& other);

    ~wp();  
    ...
    // promotion to sp
    
    sp<T> promote() const;

    // Reset
    
    void clear();

    // Accessors
    
    inline  weakref_type* get_refs() const { return m_refs; }
    
    inline  T* unsafe_get() const { return m_ptr; }
    ...
private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;

    T*              m_ptr;
    weakref_type*   m_refs;
};
template <typename T>
class sp
{
public:
    inline sp() : m_ptr(0) { }

    sp(T* other);
    sp(const sp<T>& other);
    template<typename U> sp(U* other);
    template<typename U> sp(const sp<U>& other);

    ~sp();
   ...
private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;
    void set_pointer(T* ptr);
    T* m_ptr;
};

一、sp、wp的创建和析构过程

接着,我们从一个最常见的示例出发,来看看我们创建wp、sp指针时,都做了哪些工作:

class Example : public RefBase {};

int main()
{
    Example* exa = new Example;//1、创建Example指针对象
    sp<Example> sP(exa);//2、创建sP
    wp<Example> wP(exa);//3、创建wP
    return 0;
}

第一步:


定义一个RefBase的子类类型,作为sp、wp的模板类型,并创建它的一个指针对象。Example没有任何成员,使用它使用父类的构造函数:

RefBase::RefBase()
    : mRefs(new weakref_impl(this))
{
}
weakref_impl* const mRefs;//RefBase::weakref_type子类,用于管理引用计数

mRefs是RefBase::weakref_type类型的指针,这里以当前指针对象为参数初始化了该指针:

weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)//初始化强引用计数值
        , mWeak(0)//初始化若引用计数值
        , mBase(base)//mBase是RefBase*类型,指向exa
        , mFlags(0)
        , mStrongRefs(NULL)
        , mWeakRefs(NULL)
        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
        , mRetain(false)
    {
    }

初始化完成后,第一步的工作就结束了,它主要创建了一个引用计数管理对象,并进行了一些初始化工作。

接着看第二步:
sp的构造函数有多个,这里只看最常见的接收指针类型参数的部分:

template<typename T>
sp<T>::sp(T* other)
        : m_ptr(other) {//m_ptr指向模板类型的实例指针
    if (other)
        other->incStrong(this);
}

这里模板类型T就是Example,简单地调用Example的incStrong()方法。由Example的继承关系可知,实际调用的是父类RefBase的同名方法:

void RefBase::incStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;//RefBase::weakref_type子类
    refs->incWeak(id);//通过原子操作,为弱引用计数值+1;第一次引用时,对象的弱引用计数值为1
    
    refs->addStrongRef(id);//调试作用
    const int32_t c = android_atomic_inc(&refs->mStrong);//通过原子操作,为强引用计数值+1,并返回操作之前的旧值;初始值是 1 << 28
    ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
    ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    if (c != INITIAL_STRONG_VALUE)  {//( 1 << 28 ),如果不为初始值,说明,该对象已经被强引用了。这时,直接return;
        return;
    }

    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);//再执行一次原子加法操作,第一次引用时,此时强引用计数值应为1
    refs->mBase->onFirstRef();//然后在调用该模板类型对象的onFirstRef()方法,这里我们要注意:当一个对象第一次被强引用时,会调用该方法;所以,我们可以在
    						  //该函数中做一些初始化操作,此时作用类似于构造函数,Media部分就有这种设计.
}

至此,一个强引用的创建过程就结束了;我们要记住的是:

  1. 一个sp构造完成后,它内部的对该对象的强引用和弱引用计数都为1
  2. 一个sp构造时,会调用一次模板类型的onFirstRef()函数

再看第三步:


template<typename T>
wp<T>::wp(T* other)
    : m_ptr(other)//m_ptr是指向模板类型的一个指针成员变量
{
    if (other) m_refs = other->createWeak(this);//m_refs是指向RefBase::weakref_type类型的指针,它管理引用计数
}

跟前面类似,调用:


RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
    mRefs->incWeak(id);//mRefs是RefBase::weakref_type子类型

    return mRefs;
}

调用RefBase::weakref_type::incWeak():


void RefBase::weakref_type::incWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);//weakref_impl是RefBase::weakref_type的子类
    impl->addWeakRef(id);//调试作用
    const int32_t c __unused = android_atomic_inc(&impl->mWeak);//将impl的mWeak计数值,通过原子操作+1;对于第一次被引用,此时该对象的弱引用计数为2
    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}

整个sp、wp的构建过程就结束了,看到这里,我们应该知道:


  • sp中有一个模板类型指针,指向一个实际的模板类型指针变量;而wp中除了有这样一个变量外,还有一个成员变量指向RefBase::weakref_type类型,用于管理引用计数
  • 当一个实际对象经过sp和wp创建后,它的强引用计数值为1,而弱引用计数值为2
template<typename T>
wp<T>::~wp()
{
    if (m_ptr) m_refs->decWeak(this);//m_refs是RefBase::weakref_type类型
}

直接看它的decWeak()函数:


void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);//调试不管
    const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为1;原值是2
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;//c=2,return掉

	//判断了一些生命周期标志的情况,如果c值是1,则表明弱引用计数值已经是0了,对象没有被弱引用,此时需要考虑声明周期以及对象释放操作
    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong == INITIAL_STRONG_VALUE) {//如果我们的强引用计数为默认值,则表示该对象没有强引用,需要删除对象
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {//否则删除引用计数管理对象
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
        impl->mBase->onLastWeakRef(id);
        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
            // is gone, we can destroy the object.
            delete impl->mBase;//删除实际对象
        }
    }
}



此时模板对象的强引用和弱引用计数值皆为1。

再看sp的析构函数:


template<typename T>
sp<T>::~sp() {
    if (m_ptr)
        m_ptr->decStrong(this);
}

调用:


void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);//调试不管
    const int32_t c = android_atomic_dec(&refs->mStrong);//强引用计数值减1,此时强引用计数为0;c = 1
#if PRINT_REFS
    ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
    if (c == 1) {
        refs->mBase->onLastStrongRef(id);//函数体为空,无任何操作
        if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {//自身对象有可能会被删除;mFlags默认值为0,未设置时条件成立
            delete this;//删除自身,这里的this就是实际模板对象,会触发Example的析构调用
        }
    }
    refs->decWeak(id);//此时弱引用计数为1,强引用计数值已经为0,再对弱引用计数做一次原子减法
}
void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);//调试不管
    const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为0;原值c=1
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;//c=1

	//判断了一些生命周期标志的情况,如果我们没有设置mFlags,则满足此项
    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {//此时强弱引用计数皆为0,再将计数管理对象删除
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong == INITIAL_STRONG_VALUE) {//此时不满足
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {//删除引用计数管理对象
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
        impl->mBase->onLastWeakRef(id);
        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
            // is gone, we can destroy the object.
            delete impl->mBase;//删除实际对象
        }
    }
}

再看Example对象的析构过程:


RefBase::~RefBase()
{
    if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
        // we never acquired a strong (and/or weak) reference on this object.
        delete mRefs;
    } else {
        // life-time of this object is extended to WEAK or FOREVER, in
        // which case weakref_impl doesn't out-live the object and we
        // can free it now.
        if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
            // It's possible that the weak count is not 0 if the object
            // re-acquired a weak reference in its destructor
            if (mRefs->mWeak == 0) {
                delete mRefs;
            }
        }
    }
    // for debugging purposes, clear this.
    const_cast<weakref_impl*&>(mRefs) = NULL;
}

这样,所有的对象都已经删除掉。由上可知,强引用计数值为0时,会导致实际对象被删除;弱引用计数值为0时,会导致计数管理对象被删除。





BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);//拓展生命周期
    IPCThreadState::self()->incWeakHandle(handle);
}

BpBinder是RefBase的子类,它在构造函数中调用了extendObjectLifetime()函数来拓展它的生命周期。我们把这个调用加进我们的示例中,并来分析下该调用的实际意义:


class Example : public RefBase {
   extendObjectLifetime(OBJECT_LIFETIME_WEAK);//拓展生命周期
};

int main()
{
    Example* exa = new Example;//1、创建Example指针对象
    sp<Example> sP(exa);//2、创建sP
    wp<Example> wP(exa);//3、创建wP
    return 0;
}

从上面的分析可知,extendObjectLifetime()并不影响sp、wp的创建流程;所以还是需要从示例的析构过程着手。



void RefBase::extendObjectLifetime(int32_t mode)
{
    android_atomic_or(mode, &mRefs->mFlags);
}



enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };

它只会设置Example的成员变量mFlags;由之前的介绍可知wp的析构函数会调用到:


void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);//调试不管
    const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为1;原值c=2
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;//c=2,直接return

    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong == INITIAL_STRONG_VALUE) {
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
        impl->mBase->onLastWeakRef(id);
        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
            // is gone, we can destroy the object.
            delete impl->mBase;
        }
    }
}

由于此时c=2,直接return掉;再看sp的析构调用,由之前介绍,会调用到:


void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);
    const int32_t c = android_atomic_dec(&refs->mStrong);//强引用计数值减1,此时强引用计数为0;c = 1
#if PRINT_REFS
    ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
    if (c == 1) {
        refs->mBase->onLastStrongRef(id);//函数体为空,无任何操作
        if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {//我们设置了mFlags:OBJECT_LIFETIME_WEAK,不满足if条件;在强引用计数值为0时,我们没有删掉模板类型对象
            delete this;
        }
    }
    refs->decWeak(id);//此时弱引用计数为1,再对弱引用计数做一次原子减法
}

由于我们设置了mFlags的值,代码中的if条件并不满足,此时并不会删除掉原始对象,即模板类型实例。再看decWeak():


void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);//调试不管
    const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为0;原值c=1
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;//c=1

	//我们设置了mFlags:OBJECT_LIFETIME_WEAK,此时if条件并不满足,走else分支
    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong == INITIAL_STRONG_VALUE) {
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
        impl->mBase->onLastWeakRef(id);
        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {//设置的mFlags满足此条件,所以会删除掉模板类型对象
            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
            // is gone, we can destroy the object.
            delete impl->mBase;//删除模板类型对象,即原始对象
        }
    }
}

原始对象的删除会调用它的析构函数:


RefBase::~RefBase()
{
    if (mRefs->mStrong == INITIAL_STRONG_VALUE) {//mStrong此时为0,不满足if条件
        // we never acquired a strong (and/or weak) reference on this object.
        delete mRefs;
    } else {
        // life-time of this object is extended to WEAK or FOREVER, in
        // which case weakref_impl doesn't out-live the object and we
        // can free it now.
        //设置了mFlags后,此条件满足
        if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
            // It's possible that the weak count is not 0 if the object
            // re-acquired a weak reference in its destructor
            if (mRefs->mWeak == 0) {//弱引用计数经历过两次删除后,mWeak为0
                delete mRefs;//删除计数管理对象
            }
        }
    }
    // for debugging purposes, clear this.
    const_cast<weakref_impl*&>(mRefs) = NULL;//调试,置空指针
}

在析构函数中,引用计数管理对象被删除。由此,我们得出:当我们设置mFlags为OBJECT_LIFETIME_WEAK时,只有当强引用计数和弱引用计数值都为0时,模板类型对象和引用计数对象才会被删除;这明显和前面介绍的没有设置mFlags的过程不同。




二、类型提升



template<typename T>
sp<T> wp<T>::promote() const
{
    sp<T> result;
    if (m_ptr && m_refs->attemptIncStrong(&result)) {
        result.set_pointer(m_ptr);
    }
    return result;
}

考虑这种使用场景,来看看它的内部处理流程:


class Example : public RefBase {};

int main()
{
    Example* exa = new Example;
    wp<Example> wP(exa);
    sp<Example> sP = wP.promote();//类型提升
    return 0;
}

当我们创建完wP时,此时强引用计数值应为0,弱引用计数值为1。看attemptIncStrong():


bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    incWeak(id);//原子加法操作,若引用计数加1,此时过后,弱引用计数为2
    
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    int32_t curCount = impl->mStrong;//此时应为初始值0

    ALOG_ASSERT(curCount >= 0,
            "attemptIncStrong called on %p after underflow", this);

    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
        // we're in the easy/common case of promoting a weak-reference
        // from an existing strong reference.
        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
            break;
        }
        // the strong count has changed on us, we need to re-assert our
        // situation.
        curCount = impl->mStrong;
    }
    
    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
        // we're now in the harder case of either:
        // - there never was a strong reference on us
        // - or, all strong references have been released
        if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {//走else分支
            // this object has a "normal" life-time, i.e.: it gets destroyed
            // when the last strong reference goes away
            if (curCount <= 0) {
                // the last strong-reference got released, the object cannot
                // be revived.
                decWeak(id);
                return false;
            }

            // here, curCount == INITIAL_STRONG_VALUE, which means
            // there never was a strong-reference, so we can try to
            // promote this object; we need to do that atomically.
            while (curCount > 0) {
                if (android_atomic_cmpxchg(curCount, curCount + 1,
                        &impl->mStrong) == 0) {
                    break;
                }
                // the strong count has changed on us, we need to re-assert our
                // situation (e.g.: another thread has inc/decStrong'ed us)
                curCount = impl->mStrong;
            }

            if (curCount <= 0) {
                // promote() failed, some other thread destroyed us in the
                // meantime (i.e.: strong count reached zero).
                decWeak(id);
                return false;
            }
        } else {
            // this object has an "extended" life-time, i.e.: it can be
            // revived from a weak-reference only.
            // Ask the object's implementation if it agrees to be revived
            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {//是否允许强引用加1,此场景下是允许的,返回TRUE
                // it didn't so give-up.
                decWeak(id);
                return false;
            }
            // grab a strong-reference, which is always safe due to the
            // extended life-time.
            curCount = android_atomic_inc(&impl->mStrong);//强引用计数加1,开始处弱引用计数已经加1了
        }

        // If the strong reference count has already been incremented by
        // someone else, the implementor of onIncStrongAttempted() is holding
        // an unneeded reference.  So call onLastStrongRef() here to remove it.
        // (No, this is not pretty.)  Note that we MUST NOT do this if we
        // are in fact acquiring the first reference.
        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
            impl->mBase->onLastStrongRef(id);//无任何操作
        }
    }
    
    impl->addStrongRef(id);

#if PRINT_REFS
    ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif

    // now we need to fix-up the count if it was INITIAL_STRONG_VALUE
    // this must be done safely, i.e.: handle the case where several threads
    // were here in attemptIncStrong().
    curCount = impl->mStrong;
    while (curCount >= INITIAL_STRONG_VALUE) {
        ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
                "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
                this);
        if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
                &impl->mStrong) == 0) {
            break;
        }
        // the strong-count changed on us, we need to re-assert the situation,
        // for e.g.: it's possible the fix-up happened in another thread.
        curCount = impl->mStrong;
    }

    return true;
}

代码中给该对象的强弱引用计数值都自加了1,此时就对象的强引用计数值为1,弱引用计数值为2了。


template<typename T>
void sp<T>::set_pointer(T* ptr) {
    m_ptr = ptr;
}

再将实际对象指针保存到sp中。





PS:在Android native代码中,一般的对象指针都已经被sp、wp等代替了,用了它们,我们无需手动去回收指针对象,这样极大地提升了程序的稳定性。而在大多数的native程序中,sp、wp都只是一个代替普通指针的工具,我们能了解它的原理更好,不了解的话,就把它们当中普通指针来看待就行了。



我觉得这些内容中最要注意的一点就是sp第一次构建完成后,会调用实际对象的onFirstRef()函数;在有些场景中,这一点会很容易被忽略,但确实有一些程序会在onFirstRef()方法中做一些初始化操作;如果不记住这点,碰到这种情况,我们看代码时,可能会觉得有一些困惑,而这个困惑恰恰是可以避免的。