千家信息网

Android的引用计数怎么实现

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Android的引用计数怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android的引用计数怎么实现"吧!1:问题不像java
千家信息网最后更新 2026年11月03日Android的引用计数怎么实现

本篇内容主要讲解"Android的引用计数怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android的引用计数怎么实现"吧!

1:问题

不像java这种runtime提供内存回收机制的语言,c c++开发中经常困扰开发者的是变量的分配与回收,当new完对象而忘记delete就会造成内存泄漏,如果delete了还在别处引用当对象,就会形成野指针

2:解决

一种内存回收策略叫引用计数,当对象被引用时,引用计数就+1,不再引用的时候引用计数就-1,当引用计数为0时,就回收对象。这种内存回收机制的问题是不能回收循环引用的对象,a对象有b对象的引用,同时b对象持有a对象的引用,就会出现a,b对象的引用数永远不可能为零的情况出现。

Android最简单的引用计数实现

template 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(this);        }    }    //! DEBUGGING ONLY: Get current strong ref count.    inline int32_t getStrongCount() const {        return mCount.load(std::memory_order_relaxed);    }    typedef LightRefBase 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 mCount;};

仅仅是通过± mCount的值来进行判断变量是否还有引用引用,如果引用数降为零则会调用 delete static_cast(this);析构函数

智能指针

sp strongPointer
wp weakPointer
这两个类的共同基类是refbase.cpp

使用场景:

在framework native 代码中经常会有如下用法

sp proc = ProcessState::self();sp ProcessState::self(){    Mutex::Autolock _l(gProcessMutex);    if (gProcess != nullptr) {        return gProcess;    }    gProcess = new ProcessState(kDefaultDriver);    return gProcess;}

通过=操作符初始化sp

template templatesp& sp::operator =(sp&& other) {    T* oldPtr(*const_cast(&m_ptr));    if (m_ptr) m_ptr->decStrong(this);    if (oldPtr != *const_cast(&m_ptr)) sp_report_race();    m_ptr = other.m_ptr;    other.m_ptr = nullptr;    return *this;}

mptr是指向范性类型的指针 T*,T类型都是RefBase类型的派生类。如果之前有值会decStrong,并且将m_ptr指向新的RefBase类型的派生类
下面详细说下RefBase的incStrong与decStrong及WeakRef_type的incWeak与decWeak方法,整个引用计数计算方式及引用计数引起的对象构造,析构都围绕这四个方法展开。

特别关注
RefBase引用类型定义

 enum {        OBJECT_LIFETIME_STRONG  = 0x0000,        OBJECT_LIFETIME_WEAK    = 0x0001,        OBJECT_LIFETIME_MASK    = 0x0001    };

及weakRef_impl类的四个成员变量

    std::atomic    mStrong;  //线程原子操作变量    std::atomic    mWeak;   //线程原子操作变量    RefBase* const          mBase;    std::atomic    mFlags;   //线程原子操作变量        explicit weakref_impl(RefBase* base)        : mStrong(INITIAL_STRONG_VALUE)        , mWeak(0)        , mBase(base)        , mFlags(0)    {    }

incWeak

void RefBase::weakref_type::incWeak(const void* id){    weakref_impl* const impl = static_cast(this);    impl->addWeakRef(id); //非debug模式什么也不做    const int32_t c __unused = impl->mWeak.fetch_add(1,            std::memory_order_relaxed); //impl变量mWeak线程安全模式+1    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);}

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);// mStrong成员变量+1      if (c != INITIAL_STRONG_VALUE)  { //如果不是第一次强引用计数+1则直接返回        return;    }    //如果是第一次则会把mStrong的初始值减去也就是使它的值 从1开始计算    int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);    ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);    refs->mBase->onFirstRef(); //第一次会回调onFirstRef}

decWeak

void RefBase::weakref_type::decWeak(const void* id){    weakref_impl* const impl = static_cast(this);    impl->removeWeakRef(id);    const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);  //mWeak变量值线程安全-1     if (c != 1) return;    //如果引用计数值>1及不止一个sp引用到这个变量,则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) {//如果mstrong是初始值,也就是没有执行过incStrong            // 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.        //如果是弱引用并且是最后一个引用则会回调 onLastWeakRef方法        impl->mBase->onLastWeakRef(id);        delete impl->mBase;  //析构对象本身    }}

析构函数

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        //如果是弱引用并且引用计数是0        if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {            delete mRefs; //析构impl类        }    } 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(mRefs) = nullptr;}

到此,相信大家对"Android的引用计数怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

对象 变量 类型 线程 内存 方法 原子 指针 第一次 安全 也就是 内容 函数 成员 指向 机制 模式 问题 学习 开发 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技活动banner 广州互联网科技公司 有马互联网科技 苏州互联网科技贷款公司 互联网科技logo设计 互联网科技美容 中国最先进互联网科技公司 成都玖崟互联网科技有限公司乐商圈怎么样 深圳前海聚择互联网科技有限公司 阿里巴巴算科技企业还是互联网 互联网科技中介 以后互联网后是啥科技 厦门比较好的科技互联网公司 湖南一路畅行互联网科技 广西互联网科技孵化中心 翼展科技 首家互联网医院 中国互联网有什么科技 2021世界互联网领先科技成果发布 科技互联网公司两年变化 互联网科技创新方面的资料 互联网科技公司排名 华服互联网科技怎么样 互联网科技工作委员会毛军 互联网电商科技 蓝色互联网科技 乌鲁木齐新华智原互联网科技学校 互联网行业科技股 晋城互联网科技 沐思想互联网科技有限公司 济南小医互联网科技有限公司招聘
0