基于Android P源码分析,加深对RefBase、sp、wp的理解。
前言 Android源码中存在大量C++代码,里面涉及智能指针的使用,除了标准库的std::shared_ptr和std::weak_ptr,还有sp/wp搭配RefBase通过强弱引用计数实现对c++对象回收机制的管理。
相关代码位于:
1 2 3 4 system/core/libutils/include/utils/RefBase.h /system/core/libutils/include/util/StrongPointer.h system/core/libutils/RefBase.cpp system/core/libutils/StrongPointer.cpp
类图关系如下:
sp模板类 [ StrongPointer.h ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 template<typename T> class sp { public: inline sp() : m_ptr(0) { } sp(T* other); // NOLINT(implicit) sp(const sp<T>& other); sp(sp<T>&& other); template<typename U> sp(U* other); // NOLINT(implicit) template<typename U> sp(const sp<U>& other); // NOLINT(implicit) template<typename U> sp(sp<U>&& other); // NOLINT(implicit) ~sp(); // Assignment sp& operator = (T* other); sp& operator = (const sp<T>& other); sp& operator = (sp<T>&& other); template<typename U> sp& operator = (const sp<U>& other); template<typename U> sp& operator = (sp<U>&& other); template<typename U> sp& operator = (U* other); //! Special optimization for use by ProcessState (and nobody else). void force_set(T* other); // Reset void clear(); //指针访问重载 inline T& operator* () const { return *m_ptr; } inline T* operator-> () const { return m_ptr; } inline T* get() const { return m_ptr; } inline explicit operator bool () const { return m_ptr != nullptr; } //操作符重载 COMPARE(==) COMPARE(!=) COMPARE(>) COMPARE(<) COMPARE(<=) COMPARE(>=) private: template<typename Y> friend class sp; template<typename Y> friend class wp; void set_pointer(T* ptr); T* m_ptr; //对应类的指针 };
sp构造函数和赋值函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 template<typename T> sp<T>::sp(T* other) : m_ptr(other) { if (other) other->incStrong(this); } template<typename T> sp<T>::sp(const sp<T>& other) : m_ptr(other.m_ptr) { if (m_ptr) m_ptr->incStrong(this); } template<typename T> sp<T>& sp<T>::operator =(const sp<T>& other) { // Force m_ptr to be read twice, to heuristically check for data races. T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); T* otherPtr(other.m_ptr); if (otherPtr) otherPtr->incStrong(this); if (oldPtr) oldPtr->decStrong(this); if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); m_ptr = otherPtr; return *this; } template<typename T> sp<T>& sp<T>::operator =(T* other) { T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); if (other) other->incStrong(this); if (oldPtr) oldPtr->decStrong(this); if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); m_ptr = other; return *this; }
以surfaceflinger服务为例,main_surfaceflinger.cpp中有以下代码,这里既有sp构造函数,又有sp赋值构造函数。其中ProcessState继承于RefBase,所以初始化过程会初始化其父类RefBase。
1 2 3 4 5 6 7 8 int main(int, char**) { ... // start the thread pool sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); ... }
RefBase构造函数 RefBase的构造函数,首先构造weakref_impl对象,这里的this指向当前对象的指针,该对象应该继承于RefBase。
1 2 3 4 RefBase::RefBase() : mRefs(new weakref_impl(this)) { }
weakref_impl weakref_impl的成员变量mBase为ProcessState指针,最终会调用目标对象的incStrong()方法,这里是RefBase::incStrong()方法。
1 2 3 4 5 6 7 8 9 10 11 weakref_impl(RefBase* base) : mStrong(INITIAL_STRONG_VALUE) //强引用计数 0x10000000 , mWeak(0) //弱引用计数为0 , mBase(base) //继承类对象的指针 , mFlags(0) , mStrongRefs(NULL) , mWeakRefs(NULL) , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) , mRetain(false) { }
incStrong 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id); refs->addStrongRef(id); const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed); 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) { return; } int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed); // A decStrong() must still happen after us. ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old); refs->mBase->onFirstRef(); }
首先调用weakref_impl的incWeak()增加的指针弱引用计数,同时增加mStrong指针强引用计数;当首次引用该对象时,回调目标对象的onFirstRef()方法。
incWeak 1 2 3 4 5 6 7 8 9 10 11 12 void RefBase::weakref_type::incWeak(const void* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->addWeakRef(id); 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 addWeakRef(const void* id) { addRef(&mWeakRefs, id, mWeak.load(std::memory_order_relaxed)); }
weakref_impl是weakref_type的子类,首先增加weakref_impl中mWeak的弱引用计数,所以此时mWeak和mStrong引用计数都为1。当sp对象ProcessState退出作用域时,就会调用对应析构函数释放该对象。
RefBase析构函数 sp析构函数 1 2 3 4 5 template<typename T> sp<T>::~sp() { if (m_ptr) m_ptr->decStrong(this); }
m_ptr保存对象,该对象继承于RefBase,所以析构函数会调用RefBase::decStrong()方法。
decStrong 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void RefBase::decStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->removeStrongRef(id); const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release); LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times", refs); if (c == 1) { std::atomic_thread_fence(std::memory_order_acquire); refs->mBase->onLastStrongRef(id); int32_t flags = refs->mFlags.load(std::memory_order_relaxed); if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { delete this; // The destructor does not delete refs in this case. } } refs->decWeak(id); }
对mStrong强引用计数执行减1操作,如果操作之前mStrong就是1,回调目标对象的onLastStrongRef()方法。如果当前flags设置对象的生命周期由强引用计数决定,那么就会释放该目标对象,最后调用decWeak()减少弱引用计数。
decWeak 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 void RefBase::weakref_type::decWeak(const void* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->removeWeakRef(id); //mWeak执行减1操作 const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release); LOG_ALWAYS_FATAL_IF(BAD_WEAK(c), "decWeak called on %p too many times", this); if (c != 1) return; atomic_thread_fence(std::memory_order_acquire); int32_t flags = impl->mFlags.load(std::memory_order_relaxed); if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 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 { delete impl; //释放weakref_impl对象 } } else { impl->mBase->onLastWeakRef(id); delete impl->mBase; //释放实际目标对象 } }
对mWeak执行减1操作,如果操作前mWeak不等于1,表示还有其他wp引用,这里直接返回;如果mWeak等于1,表示没有其他wp引用,这里需要释放目标对象和weakref_impl对象。如果flags设定目标对象的生命周期由强引用计数决定,则释放weakref_impl对象,目标对象已经在调用decWeak()方法前被释放;如果flags设定目标对象的生命周期由弱引用计数决定,则调用目标对象的onLastWeakRef()方法,然后释放目标对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 RefBase::~RefBase() { int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed); if ((flags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) { delete mRefs; } } else if (mRefs->mStrong.load(std::memory_order_relaxed) == INITIAL_STRONG_VALUE) { LOG_ALWAYS_FATAL_IF(mRefs->mWeak.load() != 0, "RefBase: Explicit destruction with non-zero weak " "reference count"); delete mRefs; } const_cast<weakref_impl*&>(mRefs) = NULL; }
在释放目标对象时,会调用到父类的析构函数,如果flags设定目标对象的生命周期由弱引用计数决定,并且mWeak计数为0,则删除weakref_impl对象;如果没有sp引用该目标对象,释放weakref_impl对象。
总结 RefBase是Android C++类的父类,有一个成员变量mRefs为weakref_impl类型指针,weakref_impl是weakref_type的子类,用来管理引用计数。
首次调用对象incStrong(),则会调用该对象的onFirstRef();调用decStrong()的最后一次,则调用该对象的onLastStrongRef()。
弱引用不能直接操作目标对象,因为wp模版类没有实现指针引用的重载,而sp模版类则实现了指针引用的重载,但是可以通过promote()函数将弱引用提升为强引用对象。
1 2 3 4 5 6 7 8 9 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; }