在AOSP中,Google实现了一套特有的智能指针系统,用来方便C++工程中的内存管理。内存释放是C++工程中非常难处理的一部分,为此一些C++工程都会有自己的智能指针系统,C++11的std中也提供了auto_ptr之类的智能指针的概念。
我们先看下C++ 11中的auto_ptr
,这个比AOSP中的较容易理解。
auto_ptr在memory.h
中,Android NDK中也包含此文件,我们可以直接使用std命名空间下面的一些方法,遗憾的是NDK把auto_ptr
这部分从memory.h
中删掉了,NDK开发没有办法使用auto_ptr。
auto_ptr的用法
// 先定义一个类
class Person {
public:
Person() {
cout << "Constructor" << endl;
}
~Person() {
cout << "deconstructor" << endl;
}
void printMsg() {
cout << "printMsg" << endl;
}
};
// main
int main() {
auto_ptr<Person> ptr(new Person);
// auto_ptr重载了->操作符,我们相当于直接对Person指针进行操作
ptr->printMsg();
return 0;
}
看下输出结果
Constructor
printMsg
deconstructor
Person的析构函数正常调用了,这是因为Person的指针的生命周期和auto_ptr绑定在一起了,而auto_ptr又是一个分配在栈中的对象,在函数返回是自动销毁,在auto_ptr的析构函数中会自动将Person指针delete。
~auto_ptr() throw() {delete __ptr_;}
auto_ptr存在不少的问题,正因为这些原因,Android团队放弃使用auto_ptr作为智能指针的方案。
auto_ptr
的析构中只写了delete,并没有使用delete[]
进行删除,所以引用指针数组是需要避免的。// 避免此写法
auto_ptr<int> ptr(new int[10]);
一个auto_ptr只能引用一个指针,不能出现两个auto_ptr引用同一个的对象的情况。如果出现了那么会造成这个指针被delete两次。
auto_ptr不能用于函数参数,函数参数中使用auto_ptr作为参数的话 ,首先会调用auto_ptr的拷贝构造函数,原先的auto_ptr会将当前引用释放,但是仍然会存在提前释放的问题。
// 不要将auto_ptr作为参数传递
int main() {
auto_ptr<Person> ptr(new Person);
foo4(ptr);
foo4(ptr);
return 0;
}
输出结果
Constructor
printMsg
deconstructor
printMsg
可以看出,析构函数在我们对这个对象操作之前进行调用了,这不是我们期望的,出现这个结果的原因是auto_ptr的原理所致,auto_ptr没有引用计数,唯一安全的使用范围就是函数内。
AOSP中有两种类型的智能指针,分别是sp和wp,sp表示强指针,强指针会进行引用计数,引用计数是透过该对象自身维持的,当这个对象的引用为0的时候,sp就会释放这个指针。
wp 表示弱指针,弱指针一般出现在两个对象循环引用的场景,如果两个对象A,B互相引用,那么这两个对象的引用计数都不为0,会出现无法释放的情况。所以如果A,B对象需要互相引用,那么A引用B,或者B引用A的时候一定需要一个弱指针,当对象的强指针计数为0时,删除该对象,如果该对象被弱指针引用,那么必须升级为强指针,否则不能进行任何操作。
如果使用sp, wp引用该对象的话, 类必须继承LightRefBase或者RefBase。
下面看下类关系图。
其中还有一个LightRefBase类,可以单独拿出来分析,它的作用跟RefBase类似,但是问题在于如果类继承自LightRefBase的话,是没有办法使用wp的。
简单来说,关键点是RefBase和LightBase的实现,这两个类管理的引用计数,sp,wp只是增加和减少引用计数。
我们看下一个测试
using namespace android;
class Object : public android::RefBase {
public:
Object() {
cout << "constructor" << endl;
}
virtual ~Object() {
cout << "deconstructor " << endl;
}
void print() {
cout << " print " << endl;
}
};
void refbaseTest() {
auto *ptr = new Object;
sp<Object> sp(ptr);
sp->print();
}
调用这个 refbaseTest时,会在堆中生成一个Object对象,然后交由智能指针进行管理,sp对象生成在栈空间,在方法返回时sp会被析构,此时会更改Object的引用计数,Object的引用计数为0时,会delete 自己。
这个是智能指针最基本的使用,但是AOSP中的使用较为复杂,可能出现下面这些情况 。
void refbaseTest() {
auto *ptr = new Object;
sp<Object> sp(ptr);
caller(sp);
}
void caller(android::sp<Object> sp){
sp->print();
}
sp作为参数传递,此时会调用sp的拷贝构造函数,此时对象引用计数会再+1,caller返回后会再-1,不会对对象释放造成影响。
我们先来看下具体实现吧,更复杂的场景稍后举例说明。
sp的定义如下:
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();
// Accessors
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; }
// Operators
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中几乎重写了所有对象常用的操作符,目的就是将所有的调用都传递给自身包含的指针,即RefBase的子类。
我们重点看下构造函数和析构函数。
//常用的构造函数
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() {
if (m_ptr)
m_ptr->decStrong(this);
}
构造函数的作用就是将引用计数加一,析构函数的作用是将引用计数减一,是否删除对象由RefBase和LightRefBase决定。
LightRefBase实现较为简单,我们先看下LightRefBase如何管理引用计数的,稍后再看下复杂的RefBase。
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;
protected:
inline ~LightRefBase() {}
private:
friend class ReferenceMover;
inline static void renameRefs(size_t /*n*/, const ReferenceRenamer & /*renamer*/) {}
inline static void renameRefId(T * /*ref*/, const void * /*old_id*/ , const void * /*new_id*/) {}
private:
mutable std::atomic<int32_t> mCount;
};
可以看出LightRefBase中有一个原子类型的mCount来进行引用计数,incStrong和decStrong均直接对该类的mCount操作。
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);
}
}
在decStrong中可以看出,如果mCount的值为0,那么就会将对象自身delete。
LightRefBase是没有办法配合wp进行使用的,LightRefBase类中没有createWeak
之类的方法 ,在模板具体化时就会报错,无法编译。
重量级的类是RefBase, 智能指针大量的逻辑都是在RefBase类中进行维护的。我们先看下这个类的定义。
class RefBase
{
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
void forceIncStrong(const void* id) const;
//! DEBUGGING ONLY: Get current strong ref count.
int32_t getStrongCount() const;
class weakref_type
{
public:
RefBase* refBase() const;
void incWeak(const void* id);
void decWeak(const void* id);
// acquires a strong reference if there is already one.
bool attemptIncStrong(const void* id);
// acquires a weak reference if there is already one.
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
// for proper use.
bool attemptIncWeak(const void* id);
//! DEBUGGING ONLY: Get current weak ref count.
int32_t getWeakCount() const;
//! DEBUGGING ONLY: Print references held on object.
void printRefs() const;
//! DEBUGGING ONLY: Enable tracking for this object.
// enable -- enable/disable tracking
// retain -- when tracking is enable, if true, then we save a stack trace
// for each reference and dereference; when retain == false, we
// match up references and dereferences and keep only the
// outstanding ones.
void trackMe(bool enable, bool retain);
};
weakref_type* createWeak(const void* id) const;
weakref_type* getWeakRefs() const;
//! DEBUGGING ONLY: Print references held on object.
inline void printRefs() const { getWeakRefs()->printRefs(); }
//! DEBUGGING ONLY: Enable tracking of object.
inline void trackMe(bool enable, bool retain)
{
getWeakRefs()->trackMe(enable, retain);
}
typedef RefBase basetype;
protected:
RefBase();
virtual ~RefBase();
//! Flags for extendObjectLifetime()
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void extendObjectLifetime(int32_t mode);
//! Flags for onIncStrongAttempted()
enum {
FIRST_INC_STRONG = 0x0001
};
// Invoked after creation of initial strong pointer/reference.
virtual void onFirstRef();
// Invoked when either the last strong reference goes away, or we need to undo
// the effect of an unnecessary onIncStrongAttempted.
virtual void onLastStrongRef(const void* id);
// Only called in OBJECT_LIFETIME_WEAK case. Returns true if OK to promote to
// strong reference. May have side effects if it returns true.
// The first flags argument is always FIRST_INC_STRONG.
// TODO: Remove initial flag argument.
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
// Invoked in the OBJECT_LIFETIME_WEAK case when the last reference of either
// kind goes away. Unused.
// TODO: Remove.
virtual void onLastWeakRef(const void* id);
private:
friend class weakref_type;
class weakref_impl;
RefBase(const RefBase& o);
RefBase& operator=(const RefBase& o);
private:
friend class ReferenceMover;
static void renameRefs(size_t n, const ReferenceRenamer& renamer);
static void renameRefId(weakref_type* ref,
const void* old_id, const void* new_id);
static void renameRefId(RefBase* ref,
const void* old_id, const void* new_id);
weakref_impl* const mRefs;
};
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
可以看出,初始化了一个weakref_impl对象,
mRefs是一个weakref_impl对象指针,我们暂时将他们称为影子对象,这个影子对象的负责维护RefBase中的强弱引用个数。
看下RefBase的incStrong实现
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中的mStrong和mWeak分别加一,mWeak加一是通过incWeak方法进行的。
如果是第一次获得对象引用的话,回调onFirstRef方法。
weak_impl中incWeak方法
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);
}
decStrong的实现
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);
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.
//
// Since we're doing atomic loads of `flags`, the static analyzer assumes
// they can change between `delete this;` and `refs->decWeak(id);`. This is
// not the case. The analyzer may become more okay with this patten when
// https://bugs.llvm.org/show_bug.cgi?id=34365 gets resolved. NOLINTNEXTLINE
// 减少弱引用计数
refs->decWeak(id);
}
decStrong的逻辑如下,如果mStrong的个数为0并且该对象的生命周期是由强引用控制,那么就调用delete this将自己删除。
flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG
这个表示对象的生命周期根据强引用还是弱引用控制的,默认是强引用。
如果调用delete this将自身删除,那么会调用RefBase的析构函数。
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;
}
但是析构函数此时并没有调用delete mRefs将weak_impl对象清除,应该是在decWeak中进行清除。
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;
// 如果弱引用为0
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 {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
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;
}
}
delete impl 会将weak_impl清除,至此该对象的生命周期就彻底走完了。
下面我们看下弱引用控制的情况,RefBase同时支持强引用计数和弱引用计数,对象的生命周期默认是由强引用进行管理的,可以使用extendObjectLifetime
将该对象的生命周期扩展成弱引用,即弱引用为0时,才会调用delete 删除自身。
wp没有办法直接获取到实际对象指针,需要升级为强引用才可以,如果升级(调用promote方法)过程中对象已经被删除,那么promote()方法会返回空的sp,所以,使用wp的时候需要判断下是否为NULL。
void refbaseTest() {
wp<Object> ptr(new Object);
sp<Object> s_ptr = ptr.promote();
if (s_ptr.get()) {
s_ptr->print();
}
}
这个时候,使用wp.promote将指针提升为sp,使用sp访问对象。
该调用的输出为
constructor
print
deconstructor
可以看出,此次promote没有返回NULL,指针升级成功。
下面看下promote失败的情况。
void refbaseTest() {
wp<Object> w_ptr2 = getwptr();
sp<Object> s_ptr = w_ptr2.promote();
if (s_ptr.get()) {
s_ptr->print();
}
}
wp<Object> getwptr() {
wp<Object> w_ptr(new Object);
w_ptr.promote();
return w_ptr;
}
先看下结果,这次promote会失败,输出结果为:
constructor
deconstructor
这次调用是在getwptr()中进行了一次promote,该对象的强引用计数+1,但是随着getwptr返回,强引用计数为0,再次promote会失败。
我们看下具体的promote逻辑。
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;
}
核心逻辑还是在attemptIncStrong里面的,如果attemptIncStrong返回false,那么会返回空的sp。
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);
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.
}
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
if (curCount <= 0) {
// the last strong-reference got released, the object cannot
// be revived.
decWeak(id);
return false;
}
while (curCount > 0) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
}
if (curCount <= 0) {
// promote() failed, some other thread destroyed us in the
// meantime (i.e.: strong count reached zero).
decWeak(id);
return false;
}
} else {
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.
curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);
}
}
}
impl->addStrongRef(id);
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
if (curCount == INITIAL_STRONG_VALUE) {
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}
代码比较长,我们分段来看。
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
}
这段逻辑是,如果强引用的计数大于0,那么直接加一,后面会返回true。
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
if (curCount <= 0) {
decWeak(id);
return false;
}
while (curCount > 0) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
}
if (curCount <= 0) {
decWeak(id);
return false;
}
}
如果这段逻辑的意思是如果是第一次promote,那么引用计数加一返回true。如果不是第一次promote了, 那么强引用计数又等于0,那么返回false,不允许升级为sp。
正好印证了上面两次的结果。
这个extendObjectLifetime
方法用来扩展对象的生命周期,让对象的生命周期是根据强引用还是弱引用进行销毁。默认是强引用。
下面看下示例
class WeakLifeCycleObject : public Object {
public:
WeakLifeCycleObject() {
// 更改生命周期
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
}
virtual ~WeakLifeCycleObject() {
}
};
void refbaseTest() {
auto *w_ptr = new WeakLifeCycleObject;
wp<WeakLifeCycleObject> wp2(w_ptr);
}
结果
constructor
de constructor
如果不更改extendObjectLifetime的话,是不会调用析构函数 的,因为这个对象的强引用个数一直是初始值。
核心删除逻辑在decWeak方法中
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;
// 如果弱引用为0
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 {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
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;
}
}
最后else这段,会先回调onLastWeakRef,然后使用delete 删除。
两者的区别很大,sp操作的引用计数是嵌入在被管理对象里面的, auto_ptr操作的引用管理是嵌入在auto_ptr里面的,也就是说,两个auto_ptr不能同时指向同一个被管理对象,但是两个sp可以指向同一个被管理对象。auto_ptr适合在小范围内局部使用,例如函数内部,不适合作为函数参数传来传去,sp可以在全局范围内使用,可以作为函数参数传来传去。两者之间的这些不同在于它们的实现方法不同,最明显的就是sp指向的对象必须要是从RefBase继承下来的,而auto_ptr指向的对象则不需要从某一个指定的类继承下来
参考:
https://blog.csdn.net/Luoshengyang/article/details/6786239
http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html
http://androidxref.com/9.0.0_r3/xref/system/core/libutils/RefBase.cpp