Android framework RefBase,sp,wp

代码位置

android-12.0.0_r28/system/core/libutils/include/utils/RefBase.h

android-12.0.0_r28/system/core/libutils/RefBase.cpp

android-12.0.0_r28/system/core/libutils/include/utils/StrongPointer.h

使用例子

#include <utils/RefBase.h>
using namespace android;
class MyClass : public RefBase {
public:
    MyClass() { printf("MyClass created\n"); }
    virtual ~MyClass() { printf("MyClass destroyed\n"); }
    virtual void onFirstRef() { printf("MyClass onFirstRef\n"); }
    virtual void onLastStrongRef(const void* id) { printf("MyClass onLastStrongRef\n"); }
};

int main(){
	MyClass* myClass = new MyClass();
	myClass->incStrong(myClass);
	myClass->decStrong(myClass);
    
    MyClass* myClass1 = new MyClass();
    sp<MyClass> spClass = myClass1;
    wp<MyClass> wpClass = myClass1;
    sp<MyClass> spClassFromwp = wpClass.promote();
	if (spClassFromwp == NULL) {
		printf("spClassFromwp is NULL\n");
	}
	return 0;
}

简介

RefBase
  • 提供对象引用计数机制:每个继承自RefBase的对象都会有一个引用计数器,用于记录对象被引用的次数。当引用计数器为0时,对象会被自动释放。
  • 提供对象内存管理机制:通过RefBase类,我们可以更好地管理对象的内存使用情况,从而减少内存泄漏和OOM错误的出现。
  • 提供线程安全性:RefBase的使用能够保证对象的线程安全性,避免多线程访问时的竞争和冲突。

在RefBase的实现中,主要包含以下几个成员函数:

  • incStrong:增加对象的引用计数。
  • decStrong:减少对象的引用计数。
  • extendObjectLifetime:延长对象的生命周期。
  • onFirstRef:在对象的第一次引用时被调用
  • onLastStrongRef:在对象的最后一个强引用被释放时被调用
  • onLastWeakRef:在OBJECT_LIFETIME_WEAK情况下,当最后一个引用结束时调用
sp模板类
  • 提供对象引用计数机制:通过sp,我们可以更方便地管理对象的引用计数,从而避免手动管理引用计数的繁琐和容易出错的问题。
  • 提供对象内存管理机制:通过sp,我们可以更好地管理对象的内存使用情况,避免内存泄漏和OOM错误的出现。
  • 提供线程安全性:sp的使用能够保证对象的线程安全性,避免多线程访问时的竞争和冲突。

在sp的实现中,主要包含以下几个成员函数:

  • sp:构造函数,用于创建sp对象。
  • get:获取sp所管理的对象的指针。
  • clear:清空sp对象所管理的指针,并将引用计数减一。
  • operator->:用于实现指针访问操作,可以方便地访问sp所管理的对象的成员函数和成员变量。
  • operator bool:用于判断sp对象是否为空,即所管理的指针是否为NULL。
wp模板类
  • 提供对象引用计数机制:通过wp,我们可以更方便地管理对象的引用计数,避免手动管理引用计数的繁琐和容易出错的问题。
  • 避免循环引用和内存泄漏:由于wp不会增加对象的引用计数,因此可以避免循环引用和内存泄漏的问题。
  • 提供对象缓存和访问控制:wp的使用可以帮助开发人员更好地管理对象的缓存和访问控制,从而提高系统性能和稳定性。

在wp的实现中,主要包含以下几个成员函数:

  • wp:构造函数,用于创建wp对象。
  • promote:将wp所管理的对象升级为sp对象。
  • clear:清空wp对象所管理的指针。

源码实现

RefBase
class RefBase
{
// ...

protected:
    RefBase();
private:
    weakref_impl* const mRefs;
// ...
};

访问权限还是 protected,那么就说明,RefBase这个类只能用作基类。

RefBase::RefBase()
    : mRefs(new weakref_impl(this))
{
}

RefBase::~RefBase()
{
    int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed);
    。。。//注释
    if ((flags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
        // It's possible that the weak count is not 0 if the object
        // re-acquired a weak reference in its destructor
        if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {
            // 释放记录引用计数的对象mRefs(weakref_impl类)
            delete mRefs;
        }
    } else {
        。。。//一些注释和打印
    }
    // 置空记录引用计数的对象mRefs(weakref_impl类)
    const_cast<weakref_impl*&>(mRefs) = nullptr;
}

RefBase 构造函数,只初始化了它的成员变量 mRefs 指针,而它被初始化为 weakref_impl 对象。

class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
    std::atomic<int32_t>    mStrong;
    std::atomic<int32_t>    mWeak;
    RefBase* const          mBase;
    std::atomic<int32_t>    mFlags;
...
    explicit weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        , mBase(base)
        , mFlags(OBJECT_LIFETIME_STRONG)
    {
    }
...
}

mStrong:代表强引用计数,初始值为 INITIAL_STRONG_VALUE = 1<<28

mWeak:代表弱引用计数

mBase:指向 RefBase 派生类对象

mFlags:代表 RefBase 派生类对象的生命周期

1、RefBase构建weakref_impl类,用于记录计数情况

2、初始化强引用计数为INITIAL_STRONG_VALUE,弱引用计数为0,默认强引用生命周期

//! Flags for extendObjectLifetime() 可以用extendObjectLifetime方法设置
	enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,// 强引用生命周期
        OBJECT_LIFETIME_WEAK    = 0x0001,// 弱引用生命周期
        OBJECT_LIFETIME_MASK    = 0x0001 // 掩码,屏蔽或过滤二进制数据中的特定位
    };
强引用计数函数:incStrong、decStrong
void RefBase::incStrong(const void* id) const
{
    weakref_impl* const refs = mRefs; //mRefs就是RefBase在构造函数传进去的weakref_impl对象
    refs->incWeak(id);//弱引用增加,看下incWeak分析

    refs->addStrongRef(id);//空实现,用作调试,重点看宏定义DEBUG_REFS的开关
    //原子操作(保证多线程安全),记录强引用说计数mStrong,增加1,返回旧值,此时c=INITIAL_STRONG_VALUE。
    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
    ....
    //如果强引用的旧值,不等于初始值INITIAL_STRONG_VALUE,那么代表现在的强引用计数为1,或2,或3,等等
    if (c != INITIAL_STRONG_VALUE)  {
        //直接return 掉,防止一直回调下面的onFirstRef()
        return;
    }

    ...
	//当首次增加强引用时,原子操作mStrong.fetch_sub时,mStrong = mStrong - INITIAL_STRONG_VALUE = 1;
    int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
    ....
    //调用成员函数onFirstRef(如果派生类有重写该类,则会调用子类的onFirstRef)
    refs->mBase->onFirstRef();
}

void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);//空实现,用作调试,重点看宏定义DEBUG_REFS的开关
    //原子操作(保证多线程安全),记录强引用mStrong计数,减阖1,返回旧值
    const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
    ...
    //当强引用计数mStrong旧值为1时
    if (c == 1) {
        std::atomic_thread_fence(std::memory_order_acquire);
        //调用成员函数onLastStrongRef
        refs->mBase->onLastStrongRef(id);
        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            //强引用生命周期(默认)时,释放RefBase对象(RefBase的派生类)
            delete this;
            // The destructor does not delete refs in this case.
        }
    }
    ...
    refs->decWeak(id);//弱引用减少,decWeak
}

incStrong增加强引用计数,并第一次增加时(即在对象的第一次引用时被调用),回调onFirstRef

decStrong减少强引用计数,并最后一次减少时(即在对象的最后一个强引用被释放时被调用),回调onLastStrongRef

弱引用计数函数:incWeak、decWeak
void RefBase::weakref_type::incWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->addWeakRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试
    //原子操作(保证多线程安全),记录弱引用mWeak计数,增加1,返回旧值
    const int32_t c __unused = impl->mWeak.fetch_add(1,
            std::memory_order_relaxed);
    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}

void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试
    //原子操作(保证多线程安全),记录弱引用mWeak计数,减去1,返回旧值
    const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);
    ...
    if (c != 1) return;
    atomic_thread_fence(std::memory_order_acquire);

    int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
    //条件1:如果是强引用生命周期(默认) 
    if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
        ....//一些注释
        //条件2:强引用计数mStrong不等于初始值INITIAL_STRONG_VALUE
        if (impl->mStrong.load(std::memory_order_relaxed)
                == INITIAL_STRONG_VALUE) {
            ....//一些注释
            ALOGW("RefBase: Object at %p lost last weak reference "
                    "before it had a strong reference", impl->mBase);
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            //则释放记录引用计数的对象mRefs(weakref_impl)
            delete impl;
        }
    } else {
        // This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
        // is gone, we can destroy the object.
        // 弱引用生命周期
        // 回调成员函数onLastWeakRef,并释放RefBase对象(派生类)
        impl->mBase->onLastWeakRef(id);
        delete impl->mBase;
    }
}

1、强引用计数的增加函数incStrong()->incWeak(),除了强引用计数mStrong加1外,弱引用计数也会mWeak也会加1

2、弱引用计数的增加函数decWeak(),只会单独对弱引用计数mWeak加1

强引用生命周期弱引用生命周期
强引用计数mStrong为0释放RefBase的派生类对象
弱引用计数mWeak为0当强引用计数非初始值时,释放记录引用计数的对象mRefs(weakref_impl类)释放RefBase对象和mRefs(weakref_impl类)对象

伪代码

decStrong(){
	1、delete this; // 即释放RefBase的派生类对象,mStrong=0
	2、refs->decWeak(id) {
        //强引用生命周期
		if(mStrong !=INITIAL_STRONG_VALUE){
			delete impl; //当强引用计数非初始值时,释放mRefs(weakref_impl,负责记录引用计数的类)对象,mWeak=0
		}else{
            //弱引用生命周期
            //释放RefBase的派生类对象,调用RefBase的析构函数(调用delete mRefs:释放记录引用计数的对象mRefs(weakref_impl类))
            delete impl->mBase; 
        }	
	}
}

3、当 RefBase 派生类对象处于强引用生命周期下,只有当强引用计数为0时,RefBase 派生类对象的动态内存才会补释放。

4、当 RefBase 派生类对象处于弱引用生命周期下,只有当弱引用计数为0时,RefBase 派生类对象的动态内存才会补释放。

sp模板类
//构造函数
template<typename T>
sp<T>::sp(T* other)
        : m_ptr(other) {
    if (other) {
        check_not_on_stack(other);
     /* 调用RefBase类的incStrong函数:强引用计数mStrong加1,弱引用计数mWeak加1
     * 此时mStrong = 1,mWeak = 1.首次增加强引用计数,回调RefBase类成员函数onFirstRef
     */
        other->incStrong(this);
    }
}            
            

//析构函数
template<typename T>
sp<T>::~sp() {
    if (m_ptr) {
    /* 调用RefBase类的decStrong函数:强引用计数mStrong减1,弱引用计数mWeak减1
     * 此时mStrong = 0,mWeak = 0.强引用计数为0,回调RefBase类成员函数onLastStrongRef并释放RefBase对象.弱引用计数为0,释放mRefs对象
     */
   	    m_ptr->decStrong(this);
    }
}

1、生命周期开始时:构造函数调用关联的RefBase对象的incStrong函数(强弱引用计数加1)
2、生命周期结束时:析构函数调用关联的RefBase对象的decStrong函数(强弱引用计数减1)

wp模板类
//构造函数
template<typename T>
wp<T>::wp(T* other)
    : m_ptr(other)
{
    m_refs = other ? m_refs = other->createWeak(this) : nullptr;
}

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
    mRefs->incWeak(id);	/* 弱引用计数加1,此时mWeak = 1 */
    return mRefs;	/* 返回记录引用计数对象mRefs */
}

//析构函数
template<typename T>
wp<T>::~wp()
{
    if (m_ptr) m_refs->decWeak(this); /* 弱引用计数减1,此时mWeak = 0,释放mRefs对象 */
}

//promote函数
template<typename T>
sp<T> wp<T>::promote() const
{
    sp<T> result;
    //判断wp<T>指向的引用m_ptr(T* m_ptr)是否被释放了,如果没有的话,将执行m_refs->attemptIncStrong(&result)
    if (m_ptr && m_refs->attemptIncStrong(&result)) {
        result.set_pointer(m_ptr);
    }
    return result;
}

//attemptIncStrong:主要逻辑就是判断该对象是不是已经回收了,实际上只要是该对象没有被回收,那么都是可以被提升到强指针
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    //弱引用计数mWeak加1	
    incWeak(id);

    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);

    ...
	//强引用计数mStrong大于0且不为初始值时
    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
        ...//注释
        // 只有mStrong的值为curCount时,才会将其值修改为curCount + 1, return true,否则修改失败,return false。    
        if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                std::memory_order_relaxed)) {
            break;
        }
        ...//注释
    }
	//之前强引用计数为0,或者为初始值
    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
        int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
        //强引用生命周期时
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            // this object has a "normal" life-time, i.e.: it gets destroyed
            // when the last strong reference goes away
            //如果强引用计数mStrong小于等于0
            if (curCount <= 0) {
                // the last strong-reference got released, the object cannot
                // be revived.
                //因此对弱引用计数mWeak减1(对应开头加1)并返回false
                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 (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                        std::memory_order_relaxed)) {
                    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 has been updated.
            }

            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)) {
                // it didn't so give-up.
                decWeak(id);
                return false;
            }
            // grab a strong-reference, which is always safe due to the
            // extended life-time.
            //弱生命周期时,mStrong加1并返回
            curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
            // 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) {
                //回调onLastStrongRef
                impl->mBase->onLastStrongRef(id);
            }
        }
    }

    impl->addStrongRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试

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

    // curCount is the value of mStrong before we incremented it.
    // 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 > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
    // this in the middle of another incStrong.  The subtraction is handled
    // by the thread that started with INITIAL_STRONG_VALUE.
    if (curCount == INITIAL_STRONG_VALUE) {
        impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
                std::memory_order_relaxed);
    }

    return true;
}

1、生命周期开始时:构造函数调用关联的RefBase对象的createWeak函数(弱引用计数加1并返回对象mRefs).
2、生命周期结束时:析构函数调用关联的mRefs对象的decWeak函数(弱引用计数减1)
3、想使用关联对象时,需调用wp成员函数promote,得到sp对象,并且要对该sp对象进行非空判断.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值