android sp(strong pointer) 和 wp(weak pointer)

来源:互联网 发布:如何屏蔽网络监控 编辑:程序博客网 时间:2024/05/01 04:09

在android中使用了sp(strong pointer) 和 wp(weak pointer)实现类似于java内存回收机制。

实现代码:

frameworks/native/libs/utils/RefBase.cpp 

frameworks/native/include/utils/RefBase.h

frameworks/native/include/utils/StrongPointer.h

强引用为0时,实际的对象会被删除

弱引用为0时,weakref_impl会被删除


强引用

sp<T>::sp(T* other)
: m_ptr(other)
{
    if (other) other->incStrong(this);
}

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


void RefBase::incStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;

//弱引用计数器增1
    refs->incWeak(id);
    

//这个只在DEBUG版本追踪时有用,现在可以不用看
    refs->addStrongRef(id);

//强引用计数器增1

    const int32_t c = android_atomic_inc(&refs->mStrong);
    ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);

//INITIAL_STRONG_VALUE的值(1<<28) ,当refs->mStrong第一次创建完后,以后就直接return了

    if (c != INITIAL_STRONG_VALUE)  {
        return;
    }

//第一次构造时,会最终使refs->mStrong == 1
    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
    refs->mBase->onFirstRef();
}


void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;

//和addStrongRef相对应
    refs->removeStrongRef(id);

//强引用计数器减1

    const int32_t c = android_atomic_dec(&refs->mStrong);

    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) {
// 当refs->mStrong == 0时,自杀删除对象

           delete this;
        }
    }
//弱引用计数器减1 

   refs->decWeak(id);
}


RefBase::~RefBase()
{
    if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
        // we never acquired a strong (and/or weak) reference on this object.
//没有使用强引用计数,直接删除weakref_impl

       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;
}