1 RefBase, sp, wp
在Android中,RefBase結(jié)合sp和wp旺入,實(shí)現(xiàn)了一套通過引用計(jì)數(shù)的方法來控制對(duì)象生命周期的機(jī)制而姐。
1.1 初識(shí)影子對(duì)象
refBase
是實(shí)現(xiàn)引用計(jì)數(shù)的基類坑夯,提供引用計(jì)數(shù)的方法喂窟。簡單示例:
class A: public RefBase {
//..
}
int main() {
A* pA = new A;
{
//sp庐椒,wp對(duì)象是在{}中創(chuàng)建的椒舵,下面的代碼先創(chuàng)建sp,然后創(chuàng)建wp
sp<A>spA(A);
wp<A>wpA(spA);
//大括號(hào)結(jié)束前约谈,先析構(gòu)wp,再析構(gòu)sp
}
}
1.1.1 RefBase和它的影子
示例代碼中 class A
繼承自RefBase
,使用的是RefBase
的構(gòu)造函數(shù)
system/core/libutils/RefBase.cpp
RefBase::RefBase()
: mRefs(new weakref_impl(this)){
}
mRefs
是RefBase
的內(nèi)部類weakref_type
的子類weakref_impl
的實(shí)例笔宿,保存在RefBase
中的一個(gè)字段。
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;
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
, mBase(base)
, mFlags(0)
, mStrongRefs(NULL)
, mWeakRefs(NULL)
, mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
, mRetain(false)
{
}
}
通過上面代碼可知棱诱,在創(chuàng)建A
對(duì)象的同時(shí)也創(chuàng)建了一個(gè)weakref_type
對(duì)象泼橘,稱為影子。
影子中的兩個(gè)字段就關(guān)系對(duì)象的生死迈勋。
1.1.2 sp
system/core/include/utils/StrongPointer.h
繼續(xù)查看實(shí)例代碼中構(gòu)造一個(gè)sp引用sp<A> spA(A)
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other)
other->incStrong(this);
}
其中T
必須繼承自RefBase
,構(gòu)建sp
引用后代碼就執(zhí)行了inctrong(this)
炬灭,該方法是RefBase
提供
system/core/libutils/RefBase.cpp
void RefBase::incStrong(const void* id) const {
//mRefs是RefBase中的字段,在RefBase構(gòu)造函數(shù)執(zhí)行時(shí)賦值
weakref_impl* const refs = mRefs;
//先增加弱引用計(jì)數(shù)
refs->incWeak(id);
//空實(shí)現(xiàn)粪躬,無視
refs->addStrongRef(id);
//原子操作担败,強(qiáng)引用增加1
const int32_t c = refs->mStrong.fetch_add(1,std::memory_order_relaxed);
#if PRINT_REFS
ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
//判斷是否為初識(shí)值
if (c != INITIAL_STRONG_VALUE) {
return;
}
//是第一引用就會(huì)執(zhí)行下面的代碼
//設(shè)置初識(shí)值
int32_t old = 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);
/*如果是第一次引用,則調(diào)用onFirstRef()
這個(gè)函數(shù)很重要镰官,派生類可以重載這個(gè)函數(shù)提前,完成一些初始化工作。*/
refs->mBase->onFirstRef();
}
incWeak(id)
函數(shù)
void RefBase::weakref_type::incWeak(const void* id) {
weakref_impl* const impl = static_cast<weakref_impl*>(this);
//空實(shí)現(xiàn)泳唠,無視
impl->addWeakRef(id);
//原子操作狈网,弱引用增加1
const int32_t c __unused = impl->mWeak.fetch_add(1,
std::memory_order_relaxed);
}
sp構(gòu)造完成后RefBase
中weakref_impl
實(shí)例的強(qiáng)弱引用都增加了1.
wp
構(gòu)造完成又是什么樣的?
system/core/include/utils/RefBase.h
template<typename T>
wp<T>::wp(T* other)
: m_ptr(other) //m_ptr就是繼承RefBase的實(shí)際對(duì)象
{
//調(diào)用pA的createWeak,并且保存返回值到成員變量m_refs中
if (other) m_refs = other->createWeak(this);
}
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
//mRefs就是那個(gè)new出來的weakref_impl實(shí)例
//增加弱引用加1
mRefs->incWeak(id);
return mRefs;
}
回到最初的示例代碼笨腥,在構(gòu)造完wp
后拓哺,A
對(duì)象的影子對(duì)象mRefs
中的mWeak
增加了2,mStrong
只增加了1脖母。
wp
中有兩個(gè)成員變量士鸥,一個(gè)保存實(shí)際對(duì)象,另一個(gè)保存影子對(duì)象谆级。sp
只有一個(gè)成員變量用來保存實(shí)際對(duì)象烤礁,但這個(gè)實(shí)際對(duì)象內(nèi)部已包含了對(duì)應(yīng)的影子對(duì)象。
1.1.3 wp,sp析構(gòu)
還是最初的回到實(shí)例代碼里肥照,我們是在代碼塊中創(chuàng)建的sp<A> spA
和wp<A> wpA
兩個(gè)對(duì)象脚仔,更具代碼的執(zhí)行,除了代碼塊舆绎,兩個(gè)對(duì)象的析構(gòu)函數(shù)就會(huì)被調(diào)用鲤脏。
system/core/include/utils/RefBase.h
wp<T>::~wp()
{
//調(diào)用影子對(duì)象的decWeak,由影子對(duì)象的基類實(shí)現(xiàn)
if (m_ptr) m_refs->decWeak(this);
}
system/core/libutils/RefBase.cpp
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
//空實(shí)現(xiàn),無視
impl->removeWeakRef(id);
//原子操作猎醇,計(jì)數(shù)減一
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);
//如果c為1窥突,則弱引用計(jì)數(shù)為0,這說明沒用弱引用指向?qū)嶋H對(duì)象姑食,需要考慮是否釋放內(nèi)存
// OBJECT_LIFETIME_XXX和生命周期有關(guān)系
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlives the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
// Decrementing a weak count to zero when object never had a strong
// reference. We assume it acquired a weak reference early, e.g.
// in the constructor, and will eventually be properly destroyed,
// usually via incrementing and decrementing the strong count.
// Thus we no longer do anything here. We log this case, since it
// seems to be extremely rare, and should not normally occur. We
// used to deallocate mBase here, so this may now indicate a leak.
ALOGW("RefBase: Object at %p lost last weak reference "
"before it had a strong reference", impl->mBase);
} else {
delete impl;
}
} else {
// This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
impl->mBase->onLastWeakRef(id);
delete impl->mBase;
}
}
繼續(xù)示例代碼波岛,wp
析構(gòu)后茅坛,弱引用計(jì)數(shù)為1音半,但是強(qiáng)引用也是1,所以不能釋放對(duì)象贡蓖。
sp析構(gòu):
system/core/include/utils/StrongPointer.h
sp<T>::~sp() {
if (m_ptr)
//m_ptr就是實(shí)際對(duì)象曹鸠,集成自RefBase
m_ptr->decStrong(this);
}
system/core/libutils/RefBase.cpp
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);
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
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);
//調(diào)用onLastStrongRef,表明強(qiáng)引用計(jì)數(shù)減為0斥铺,對(duì)象有可能被delete
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.
}
}
// Note that even with only strong reference operations, the thread
// deallocating this may not be the same as the thread deallocating refs.
// That's OK: all accesses to this happen before its deletion here,
// and all accesses to refs happen before its deletion in the final decWeak.
// The destructor can safely access mRefs because either it's deleting
// mRefs itself, or it's running entirely before the final mWeak decrement.
//weaktype_impl對(duì)象調(diào)用減少弱引用
refs->decWeak(id);
delete this
回調(diào)用被引用的析構(gòu)函數(shù)彻桃,例如示例的A
類,如果強(qiáng)引用沒有了,就把引用對(duì)象delete
RefBase::~RefBase()
{
int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed);
// Life-time of this object is extended to WEAK, in
// which case weakref_impl doesn't out-live the object and we
// can free it now.
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) {
delete mRefs;
}
} else if (mRefs->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
// We never acquired a strong reference on this object.
LOG_ALWAYS_FATAL_IF(mRefs->mWeak.load() != 0,
"RefBase: Explicit destruction with non-zero weak "
"reference count");
// TODO: Always report if we get here. Currently MediaMetadataRetriever
// C++ objects are inconsistently managed and sometimes get here.
// There may be other cases, but we believe they should all be fixed.
delete mRefs;
}
// For debugging purposes, clear mRefs. Ineffective against outstanding wp's.
const_cast<weakref_impl*&>(mRefs) = NULL;
}
sp
執(zhí)行了減少強(qiáng)引用之后將執(zhí)行減少弱引用晾蜘,如果弱引用沒有了邻眷。就把weaktype_impl
對(duì)象delete
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);
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) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlives the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
// Decrementing a weak count to zero when object never had a strong
// reference. We assume it acquired a weak reference early, e.g.
// in the constructor, and will eventually be properly destroyed,
// usually via incrementing and decrementing the strong count.
// Thus we no longer do anything here. We log this case, since it
// seems to be extremely rare, and should not normally occur. We
// used to deallocate mBase here, so this may now indicate a leak.
ALOGW("RefBase: Object at %p lost last weak reference "
"before it had a strong reference", impl->mBase);
} else {
//delete影子對(duì)象
delete impl;
}
} else {
// This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
impl->mBase->onLastWeakRef(id);
delete impl->mBase;
}
}
1.1.4 總結(jié)
RefBase
中有一個(gè)隱含的影子對(duì)象,這個(gè)對(duì)象就是實(shí)際包含被引用對(duì)象和強(qiáng)弱引用計(jì)數(shù)剔交;
sp
構(gòu)造引用后肆饶,強(qiáng)弱引用計(jì)數(shù)各增加1,sp
析構(gòu)后岖常,強(qiáng)弱引用計(jì)數(shù)各減1驯镊;
wp
構(gòu)造引用后,弱引用增加1竭鞍,wp
析構(gòu)后板惑,弱引用計(jì)數(shù)減1;
完全徹底地消滅RefBase對(duì)象偎快,包括讓實(shí)際對(duì)象和影子對(duì)象滅亡冯乘,這些都是由強(qiáng)弱引用計(jì)數(shù)控制的,另外還要考
慮flag的取值情況晒夹。當(dāng)flag為0時(shí)裆馒,可得出如下結(jié)論:
- 強(qiáng)引用為0將導(dǎo)致實(shí)際對(duì)象被delete。
- 弱引用為0將導(dǎo)致影子對(duì)象被delete惋戏。
1.2 由弱生強(qiáng)
代碼示例:
int main(){
A *pA =new A();
wp<A> wpA(A);
sp<A> spA = wpA.promote();//通過promote函數(shù)领追,得到一個(gè)sp。
}
1.2.1 由弱生強(qiáng)的方法
由示例代碼可以看出响逢,依靠函數(shù)promote()
可以得到一個(gè)sp
的對(duì)象
template<typename T>
sp<T> wp<T>::promote() const
{
sp<T> result;
//該函數(shù)就是弱生強(qiáng)的關(guān)鍵
if (m_ptr && m_refs->attemptIncStrong(&result)) {
result.set_pointer(m_ptr);
}
return result;
}
成敗全靠attemptIncStrong()
system/core/libutils/RefBase.cpp
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id); //增加弱
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);
//該循環(huán)在多線程操作同一個(gè)對(duì)象時(shí)會(huì)多次循環(huán)绒窑,他的目的就是讓強(qiáng)引用加1
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 (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. curCount was updated by compare_exchange_weak.
}
....//太長了,也看不懂舔亭,也是為了保證能裝換強(qiáng)引用
if (curCount == INITIAL_STRONG_VALUE) {
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}
1.2.2 結(jié)果
結(jié)果當(dāng)然就是強(qiáng)弱增加一個(gè)返回一個(gè)強(qiáng)引用對(duì)象些膨。
1.3 生命周期的管理
在構(gòu)造的sp
,或wp
的生命周期受flag的影響蟀俊。
system/core/include/utils/RefBase.h
//! Flags for extendObjectLifetime()
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
- 在flag為
OBJECT_LIFETIME_WEAK
時(shí),即便sp
對(duì)象的強(qiáng)引用計(jì)數(shù)為0订雾,而弱引用不為0肢预,被引用對(duì)象不會(huì)被delete,進(jìn)而在減少弱引用函數(shù)中再去判斷,如果弱引用也為0了洼哎,就會(huì)delete掉被引用對(duì)象烫映。 - 在flag為
OBJECT_LIFETIME_STRONG
強(qiáng)引用空之被引用對(duì)象的生命周期。弱引用控制影子對(duì)象的生命周期噩峦,強(qiáng)引用為0時(shí)锭沟,被引用對(duì)象delete。
1.3.1 輕量引用計(jì)數(shù)控制-LightRefBase
template <class T>
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
inline void incStrong(__attribute__((unused)) const void* id) const {
mCount.fetch_add(1, std::memory_order_relaxed);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount.load(std::memory_order_relaxed);
}
typedef LightRefBase<T> basetype;
...
private:
mutable std::atomic<int32_t> mCount;
};
這個(gè)類中僅有一個(gè)mCount
用來引用計(jì)數(shù)识补,使用也非常簡單:
class A: public LightRefBase<A> //泛型得是A
2 Thread類以及常用同步類
Thread類是Android為線程操作而做的一個(gè)封裝族淮。代碼在Thread.cpp中,其中還封裝了一些與線程同步相關(guān)的類
2.1 常見同步類
Android提供了兩個(gè)封裝好的同步類凭涂,它們是Mutex和Condition祝辣。這是重量級(jí)的同步技術(shù),一般內(nèi)核會(huì)有對(duì)應(yīng)的
支持切油。另外蝙斜,OS還提供了簡單的原子操作,這些也算是同步技術(shù)的一種白翻。
2.1.1 互斥類-Mutex
Mutex
的使用必須初始化乍炉,除此之外有兩個(gè)重要函數(shù)處理同步,lock
(),unlock()
滤馍,分別表示開始上鎖岛琼,釋放鎖。另外巢株,Mutex
還提供了一個(gè)trylock()
函數(shù)槐瑞,該函數(shù)只是嘗試去鎖住該區(qū)域,使用者需要根據(jù)trylock的返回值判
斷是否成功鎖住了該區(qū)域阁苞。
Mutex
類的內(nèi)部還有一個(gè)AutoLock
幫助簡化同步困檩。
2.1.2 條件類-Condition
工作線程通過觸發(fā)信號(hào),喚起等待的進(jìn)程那槽。Condition
的信號(hào)觸發(fā)需要在lock范圍中才可以
3 Looper和Handler
工作原理:
一個(gè)消息隊(duì)列悼沿,其他線程可以往這個(gè)隊(duì)列中添加消息。
有一個(gè)消息循環(huán)骚灸,不斷的去出消息糟趾,處理消息。![looper_handler-1]
在Android系統(tǒng)中:
Looper
用于封裝消息循環(huán),內(nèi)部有一個(gè)消息隊(duì)列
Handler
它是負(fù)責(zé)消息的入隊(duì)和消息的處理义郑。
Looper
中的消息隊(duì)列里面存的是多個(gè)Message
每個(gè)Message
中有一個(gè)Handler
蝶柿,用于處理Message