Android高级——智能指针

news/2024/7/8 7:56:06 标签: android, c++, c语言

智能指针

智能指针是一种能够自动维护对象引用计数的技术

  • 引用了一个实际使用的对象,而不是一个指针
  • 智能指针构造时,增加它所引用的对象的引用计数
  • 智能指针析构时,减少它所引用的对象的引用计数

但智能指针无法解决循环引用问题,引入强引用计数和弱引用计数

  • 对象的生命周期只受强引用计数控制
  • 将有关联的对象划分为“父-子”和“子-父”关系
  • 在“父-子”关系中,“父”对象通过强引用计数来引用“子”对象
  • 而在“子-父”关系中,“子”对象通过弱引用计数来引用“父”对象
  • 如A通过强引用计数来引用B,而B通过弱引用计数来引用A,A的生命周期不受B的影响,当A不再使用时可以安全地释放
  • 当B想要使用A时,先要成功地将A的弱引用计数升级为强引用计数,若升级失败,那么就说明A已经被释放,不能再使用

Android系统提供了三种类型的C++智能指针

  • 轻量级指针——引用计数
  • 强指针——强引用计数
  • 弱指针——弱引用技术

轻量级指针

LightRefBase

一个类的对象要支持使用轻量级指针,需继承LightRefBase,其在frameworks/rs/cpp/util/RefBase.h(Android13)

template <class T>
class LightRefBase
{
public:
    inline LightRefBase() : mCount(0) { }
    inline void incStrong(__attribute__((unused)) const void* id) const {
        __sync_fetch_and_add(&mCount, 1);
    }
    inline void decStrong(__attribute__((unused)) const void* id) const {
        if (__sync_fetch_and_sub(&mCount, 1) == 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:
    friend class ReferenceMover;
    inline static void moveReferences(void*, void const*, size_t,
            const ReferenceConverterBase&) { }

private:
    mutable volatile int32_t mCount;
};
  • 模板类,T表示对象的实际类型,需继承LightRefBase
  • mCount 描述对象的引用计数值
  • incStrong和decStrong 用来增加/减少它所引用对象的引用计数,减少到0释放内存

sp

sp用于轻量级指针,同时也用于强指针,其在frameworks/rs/cpp/util/StrongPointer.h(Android13)

template <typename T>
class sp
{
public:
    inline sp() : m_ptr(0) { }

    sp(T* other);  // NOLINT, implicit
    sp(const sp<T>& other);
    template<typename U> sp(U* other);  // NOLINT, implicit
    template<typename U> sp(const sp<U>& other);  // NOLINT, implicit

    ~sp();

    // Assignment

    sp& operator = (T* other);
    sp& operator = (const sp<T>& other);

    template<typename U> sp& operator = (const 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; }

    // 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;
};
  • 模板类,T表示对象的实际类型,需继承LightRefBase
  • m_ptr 在构造函数中初始化,指向实际引用的对象

sp类的构造函数如下,初始化m_ptr(指向LightRefBase子类),调用LightRefBase类incStrong增加它的引用计数

template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
  {
    if (other) other->incStrong(this);
  }

sp类的析构函数如下,调用 LightRefBase类decStrong 减少它的引用计数

template<typename T>
sp<T>::~sp()
{
    if (m_ptr) m_ptr->decStrong(this);
}

实例分析

external/lightpointer/lightpointer.cpp


强指针和弱指针

RefBase

一个类的对象要支持使用轻量级指针,需继承RefBase,其在frameworks/rs/cpp/util/RefBase.h(Android13)

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
    };

    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    virtual void            onLastWeakRef(const void* id);

private:
    friend class ReferenceMover;
    static void moveReferences(void* d, void const* s, size_t n,
            const ReferenceConverterBase& caster);

private:
    friend class weakref_type;
    class weakref_impl;

                            RefBase(const RefBase& o);
            RefBase&        operator=(const RefBase& o);

        weakref_impl* const mRefs;
};                                           
  • 不同于LightRefBase,使用weakref_impl对象(即mRefs)维护对象的引用计数,而非整数

weakref_impl

weakref_impl同时为对象提供了强引用计数和弱引用计数,其在./system/core/libutils/RefBase.cpp(Android13)

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;

#if !DEBUG_REFS

    explicit weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        , mBase(base)
        , mFlags(OBJECT_LIFETIME_STRONG)
    {
    }

    void addStrongRef(const void* /*id*/) { }
    void removeStrongRef(const void* /*id*/) { }
    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void addWeakRef(const void* /*id*/) { }
    void removeWeakRef(const void* /*id*/) { }
    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void printRefs() const { }
    void trackMe(bool, bool) { }

#else
	......
#endif
};
  • weakref_impl 继承了 weakref_type,并实现其中方法
  • mStrong / mWeak 描述强/弱引用计数,mBase指向它所引用对象的地址

mFlags 描述对象生命周期控制方法

  • 0:只受强引用计数影响
  • OBJECT_LIFETIME_WEAK:同时受强/弱引用计数影响
  • OBJECT_LIFETIME_FOREVER:完全不受强/弱引用计数影响

强指针

sp

强指针实现类为sp,同上

sp构造函数

T为继承RefBase的子类

template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
  {
    if (other) other->incStrong(this);
  }

实际调用RefBase的incStrong,RefBase在构造函数初始化mRefs

RefBase::RefBase()
    : mRefs(new weakref_impl(this))
{
}

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();
}

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);
}
  • 调用 incWeak 将this转为weakref_impl并调用mWeak.fetch_add增加弱引用计数
  • 调用 mStrong.fetch_add 增加强引用计数
  • 若是第一次被强指针引用,调用fetch_sub将强引用计数值设置为1(默认为INITIAL_STRONG_VALUE),然后调用 onFirstRef 处理相关业务,默认为空实现,需要子类自行实现
  • 弱引用计数>=强引用计数

sp析构函数

同理,T为继承RefBase的子类

template<typename T>
sp<T>::~sp()
{
    if (m_ptr) m_ptr->decStrong(this);
}

实际调用RefBase的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.
        }
    }
    refs->decWeak(id);
}

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) {
        ALOGW("RefBase: Explicit destruction, weak count = %d (in %p). Use sp<> to manage this "
              "object.",
              mRefs->mWeak.load(), this);

#if CALLSTACK_ENABLED
        CallStack::logStack(LOG_TAG);
#endif
    }
    // For debugging purposes, clear mRefs.  Ineffective against outstanding wp's.
    const_cast<weakref_impl*&>(mRefs) = nullptr;
}

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) {
        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 {
        impl->mBase->onLastWeakRef(id);
        delete impl->mBase;
    }
}
  • 调用 mStrong.fetch_sub 减少强引用计数
  • 当为0时调用 onLastStrongRef 处理相关业务,默认为空实现,需要子类自行实现
  • 判断 mFlags 标志位,检查生命周期是否受弱引用计数控制,若为否则释放内存并调用RefBase的析构函数
  • 在RefBase的析构函数中若发现弱引用计数为0则释放mRefs

当一个对象的强引用计数值为0时

  • 当弱引用计数值大于0,只能释放RefBase,不能释放其内部的weakref_impl(因为还有其他的弱指针通过该weakref_impl对象来引用实际的对象)
  • 当弱引用计数值为0,才可以释放weakref_impl

调用 decWeak 将this转为weakref_impl并调用 mWeak.fetch_sub 减少弱引用计数,若为0

  • 若对象的生命周期只受强引用计数控制,且对象从来没有被强指针引用过,则打印输出记录(impl->mBase好像没释放?)
  • 若对象的生命周期只受强引用计数控制,且被强指针引用过,当若弱引用计数为0时,decStrong释放该对象,decWeak释放其内部的weakref_impl
  • 若对象的生命周期受弱引用计数控制或完全不受强/弱引用计数控制,调用onLastWeakRef处理业务并释放对象

弱指针

wp

wp用于弱指针,其在frameworks/rs/cpp/util/RefBase.h(Android13)

template <typename T>
class wp
{
public:
    typedef typename RefBase::weakref_type weakref_type;

    inline wp() : m_ptr(0) { }

    explicit wp(T* other);
    wp(const wp<T>& other);
    explicit wp(const sp<T>& other);
    template<typename U> explicit wp(U* other);
    template<typename U> explicit wp(const sp<U>& other);
    template<typename U> explicit wp(const wp<U>& other);

    ~wp();

    // Assignment

    wp& operator = (T* other);
    wp& operator = (const wp<T>& other);
    wp& operator = (const sp<T>& other);

    template<typename U> wp& operator = (U* other);
    template<typename U> wp& operator = (const wp<U>& other);
    template<typename U> wp& operator = (const sp<U>& other);

    void set_object_and_refs(T* other, weakref_type* refs);

    // promotion to sp

    sp<T> promote() const;

    // Reset

    void clear();

    // Accessors

    inline  weakref_type* get_refs() const { return m_refs; }

    inline  T* unsafe_get() const { return m_ptr; }

    // Operators

    COMPARE_WEAK(==)
    COMPARE_WEAK(!=)
    COMPARE_WEAK(>)
    COMPARE_WEAK(<)
    COMPARE_WEAK(<=)
    COMPARE_WEAK(>=)

    inline bool operator == (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
    }
    template<typename U>
    inline bool operator == (const wp<U>& o) const {
        return m_ptr == o.m_ptr;
    }

    inline bool operator > (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    }
    template<typename U>
    inline bool operator > (const wp<U>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    }

    inline bool operator < (const wp<T>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    }
    template<typename U>
    inline bool operator < (const wp<U>& o) const {
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    }
                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }

private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;

    T*              m_ptr;
    weakref_type*   m_refs;
};
  • 模板类,T表示对象的实际类型,需继承RefBase
  • m_ptr 在构造函数中初始化,指向实际引用的对象
  • 使用weakref_type类型的变量m_refs维护对象的弱指针引用
  • 弱指针不可以直接操作它所引用的对象,因为它所引用的对象可能是不受弱引用计数控制的
  • 如果需要操作一个弱指针所引用的对象,需要通过promote升级为强指针

wp构造函数

T为继承RefBase的子类

template<typename T>
wp<T>::wp(T* other)
    : m_ptr(other)
{
    if (other) m_refs = other->createWeak(this);
}

实际调用RefBase的createWeak、incWeak在上面有讲

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
    mRefs->incWeak(id);
    return mRefs;
}

wp析构函数

实际调用RefBase的decWeak,在上面有讲

template<typename T>
wp<T>::~wp()
{
    if (m_ptr) m_refs->decWeak(this);
}

wp promote函数

wp没有重载*和->操作符,故不能直接操作它引用的对象,需要通过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;
}

template<typename T>
void sp<T>::set_pointer(T* ptr) {
    m_ptr = ptr;
}

m_refs是该对象内部的弱引用计数器,通过调用attemptIncStrong试图增加该对象的强引用计数,若成功则转变为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);

    ALOG_ASSERT(curCount >= 0,
            "attemptIncStrong called on %p after underflow", this);

    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;
            }

            // 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.
            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) {
                impl->mBase->onLastStrongRef(id);
            }
        }
    }

    impl->addStrongRef(id);
                                                                                                                                            654,17        79%
            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;
            }

            // 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.
            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) {
                impl->mBase->onLastStrongRef(id);
            }
        }
    }

    impl->addStrongRef(id);

#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;
}
  • incWeak 先增加弱引用计数,然后后面判断是否可以增加强引用
  • 将this转为weakref_impl

当强引用计数值大于0,且不等于INITIAL_STRONG_VALUEE,调用compare_exchange_weak增加强引用计数

当强引用计数值小于等于0,或等于INITIAL_STRONG_VALUEE

  • 当生命周期受强引用影响,若强引用小于等于0则无法升级,减少弱引用。否则增加强引用,若增加失败,则减少弱引用
  • 当生命周期受弱引用或完全不受强弱引用影响,调用onIncStrongAttempted判断对象是否允许强引用它,若允许则增加强引用,若在增加前被别人增加了,则调用onLastStrongRef

如果是第一次增加强引用,需要调用mStrong.fetch_sub修正为1

实例分析


http://www.niftyadmin.cn/n/5536890.html

相关文章

【项目管理】项目风险管理(Word原件)

风险和机会管理就是在一个项目开发过程中对风险进行识别、跟踪、控制的手段。风险和机会管理提供了对可能出现的风险进行持续评估&#xff0c;确定重要的风险机会以及实施处理的策略的一种规范化的环境。包括识别、分析、制定处理和减缓行动、跟踪 。合理的风险和机会管理应尽力…

三菱PLC 6行程序实现8电机顺序启动逆序停止

目录 概要指令概述顺序启动梯形图逆序停止梯形图 概要 这里主要用到的是三菱的位左移&#xff08;SFTL&#xff09;和右移&#xff08;SFTR&#xff09;指令来实现顺序启动和逆序停止&#xff0c;时间可自由设置&#xff0c;除了应用在电机上&#xff0c;也可以用来做跑马灯。…

有哪些在本地运行大模型的方法

前言 在本文中&#xff0c;我们将看到在本地运行任何 LLM 的不同方法 1/ LMStudio LM Studio 是一款桌面应用程序&#xff0c;用于在计算机上运行本地 LLM。链接&#xff1a;https://lmstudio.ai/ 2/ Ollama Ollama 是一款工具&#xff0c;可让您在机器上本地运行开源大型语…

“拆分盘投资:机遇与风险并存

一、引言 随着互联网技术的日新月异&#xff0c;金融投资领域迎来了前所未有的变革&#xff0c;其中拆分盘作为一种新兴的投资模式&#xff0c;正逐渐进入公众的视野。其独特的价值增长逻辑和创新的投资机制&#xff0c;为投资者开辟了新的财富增值渠道。本文旨在深入探讨拆分…

(论文版)深度学习 | 基于 VGG16-UNet 语义分割模型的猫狗图像提取研究

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本实验本项目基于 VGG16-UNet 架构&#xff0c;利用 Labelme 标注数据和迁移学习&#xff0c;构建高效准确的猫狗图像分割模型。通过编码器-解码器结构&#xff08;特征提取-上采样&#xff09;提升分割精度&#xff0c;适应不同…

【鸿蒙】第2天・装饰器・组件和页面生命周期

背景知识 &#xff11;・ArkTS 拓展了 TypeScript&#xff0c;TypeScript 拓展了 JavaScript。 增加了一些约束。 &#xff12;・ArkTS 是声明式编程。 构建对象时类似构建者设计模式。链式赋值。 装饰器 &#xff20;Component 自定义组件 Component装饰器仅能装饰str…

【Unity】RPG2D龙城纷争(七)关卡编辑器之剧情编辑

更新日期:2024年7月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、剧情编辑1.对话数据集2.对话触发方式3.选择对话角色4.设置对话到关卡5.角色与地块层级6.通关条件简介 严格来说,剧情编辑不在关卡编辑器界面中完成,只不过它仍然属于关卡编辑的范畴。…

深度学习基准模型Transformer

深度学习基准模型Transformer 深度学习基准模型Transformer&#xff0c;最初由Vaswani等人在2017年的论文《Attention is All You Need》中提出&#xff0c;是自然语言处理&#xff08;NLP&#xff09;领域的一个里程碑式模型。它在许多序列到序列&#xff08;seq2seq&#xf…