C++ 内存回收
Android智能指针原理
智能指针分为3类为轻量级指针(Light Pointer)、强指针(Strong Pointer)和弱指针(Weak Pointer)
- Android 设计了基类RefBase, 用以管理引用计数,所有类必须从RefBase派生
- 设计模板类 sp wp, 用以引用实际对象,sp强引用和wp弱引用。sp wp 声明为栈对象,作用域结束时自动调用析构函数
- 在sp wp的构造函数中,增加引用数; 在析构函数中,减少引用计数
- 设计了weakref_impl类,是RefBase的内部类,用来做真正应用计数管理,创建实际对象时,同时创建一个mRefs对象。不管强引用和弱引用,都由mRref管理
原子操作函数
system/core/libcutils/Atomic.c system/core/include/cutils/atomic-arm.h
extern ANDROID_ATOMIC_INLINE int32_t android_atomic_inc(volatile int32_t *addr)
{
return android_atomic_add(1, addr);
}
extern ANDROID_ATOMIC_INLINE int32_t android_atomic_dec(volatile int32_t *addr)
{
return android_atomic_add(-1, addr);
}
RefBase
./system/core/include/utils/RefBase.h ./system/core/libutils/RefBase.cpp
RefBase.h
// ---------------------------------------------------------------------------
class RefBase
{
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
void forceIncStrong(const void* id) const;
int32_t getStrongCount() const;
class weakref_type
{
}
protected:
RefBase();
virtual ~RefBase();
private:
friend class weakref_type;
class weakref_impl;
private:
weakref_impl* const mRefs;
};
// ---------------------------------轻量级指针------------------------------------------
template <class T>
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
inline void incStrong(__attribute__((unused)) const void* id) const {
android_atomic_inc(&mCount);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
if (android_atomic_dec(&mCount) == 1) {
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount;
}
typedef LightRefBase<T> basetype;
protected:
inline ~LightRefBase() { }
private:
mutable volatile int32_t mCount;
};
// ---------------------------------------------------------------------------
RefBase.cpp
RefBase::RefBase()
: mRefs(new weakref_impl(this)) // 真正管理引用计数
{
}
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
volatile int32_t mStrong;
volatile int32_t mWeak;
RefBase* const mBase;
volatile int32_t mFlags;
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE) // 强引用计数
, mWeak(0) // 弱引用计数
, mBase(base) // 指向实际对象
, mFlags(0) // 指定强引用控制还是弱引用控制
{
}
}
// 构造函数
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
// 析构函数
RefBase::~RefBase()
{
if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
// we never acquired a strong (and/or weak) reference on this object.
delete mRefs;
} else {
// life-time of this object is extended to WEAK or FOREVER, in
// which case weakref_impl doesn't out-live the object and we
// can free it now.
if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
// It's possible that the weak count is not 0 if the object
// re-acquired a weak reference in its destructor
if (mRefs->mWeak == 0) {
delete mRefs;
}
}
}
// for debugging purposes, clear this.
const_cast<weakref_impl*&>(mRefs) = NULL;
}
void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->incWeak(id);
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
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;
}
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
refs->mBase->onFirstRef();
}
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
const int32_t c = android_atomic_dec(&refs->mStrong);
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
refs->mBase->onLastStrongRef(id);
if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this;
}
}
refs->decWeak(id);
}
强指针
system/core/include/utils/StrongPointer.h
StrongPointer.h
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other)
other->incStrong(this); // 实际上调用的是RefBase 的 incStrong方法
}
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
强指针用法
Demo1
libbinder.so
./frameworks/native/libs/binder/IInterface.cpp
class IInterface : public virtual RefBase
{
public:
IInterface();
sp<IBinder> asBinder();
sp<const IBinder> asBinder() const;
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
./frameworks/av/include/camera/ICamera.h
class ICamera: public IInterface
{
}
Demo2
framework/base/media/jni/android_media_MediaRecorder.cpp
static void
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jstring packageName)
{
ALOGV("setup");
sp<MediaRecorder> mr = new MediaRecorder();
}
framework/av/media/libmedia/mediarecorder.cpp
class MediaRecorder : public BnMediaRecorderClient,
public virtual IMediaDeathNotifier
{
}
framework/av/include/media/IMediaDeathNotifier.h
class IMediaDeathNotifier: virtual public RefBase
{
}
弱指针
./system/core/include/utils/RefBase.h ./system/core/libutils/RefBase.cpp
RefBase.h
template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
inline wp() : m_ptr(0) { }
wp(T* other);
~wp();
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
T* m_ptr;
weakref_type* m_refs;
};
template<typename T>
wp<T>::wp(T* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
template<typename T>
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}