文章目录
代码位置
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
对象进行非空判断.