文章目录

  • 代码位置
  • 使用例子
  • 简介
    • RefBase
    • sp模板类
    • wp模板类
  • 源码实现
    • RefBase
      • 强引用计数函数:incStrong、decStrong
      • 弱引用计数函数:incWeak、decWeak
    • sp模板类
    • wp模板类

代码位置

android-12.0.0_r28/system/core/libutils/include/utils/RefBase.h

android-12.0.0_r28/system/core/libutils/RefBase.cpp

android-12.0.0_r28/system/core/libutils/include/utils/StrongPointer.h

使用例子

#include <utils/RefBase.h>
using namespace android;
class MyClass : public RefBase {
public:MyClass() { printf("MyClass created\n"); }virtual ~MyClass() { printf("MyClass destroyed\n"); }virtual void onFirstRef() { printf("MyClass onFirstRef\n"); }virtual void onLastStrongRef(const void* id) { printf("MyClass onLastStrongRef\n"); }
};int main(){MyClass* myClass = new MyClass();myClass->incStrong(myClass);myClass->decStrong(myClass);MyClass* myClass1 = new MyClass();sp<MyClass> spClass = myClass1;wp<MyClass> wpClass = myClass1;sp<MyClass> spClassFromwp = wpClass.promote();if (spClassFromwp == NULL) {printf("spClassFromwp is NULL\n");}return 0;
}

简介

RefBase

  • 提供对象引用计数机制:每个继承自RefBase的对象都会有一个引用计数器,用于记录对象被引用的次数。当引用计数器为0时,对象会被自动释放。
  • 提供对象内存管理机制:通过RefBase类,我们可以更好地管理对象的内存使用情况,从而减少内存泄漏和OOM错误的出现。
  • 提供线程安全性:RefBase的使用能够保证对象的线程安全性,避免多线程访问时的竞争和冲突。

在RefBase的实现中,主要包含以下几个成员函数:

  • incStrong:增加对象的引用计数。
  • decStrong:减少对象的引用计数。
  • extendObjectLifetime:延长对象的生命周期。
  • onFirstRef:在对象的第一次引用时被调用
  • onLastStrongRef:在对象的最后一个强引用被释放时被调用
  • onLastWeakRef:在OBJECT_LIFETIME_WEAK情况下,当最后一个引用结束时调用

sp模板类

  • 提供对象引用计数机制:通过sp,我们可以更方便地管理对象的引用计数,从而避免手动管理引用计数的繁琐和容易出错的问题。
  • 提供对象内存管理机制:通过sp,我们可以更好地管理对象的内存使用情况,避免内存泄漏和OOM错误的出现。
  • 提供线程安全性:sp的使用能够保证对象的线程安全性,避免多线程访问时的竞争和冲突。

在sp的实现中,主要包含以下几个成员函数:

  • sp:构造函数,用于创建sp对象。
  • get:获取sp所管理的对象的指针。
  • clear:清空sp对象所管理的指针,并将引用计数减一。
  • operator->:用于实现指针访问操作,可以方便地访问sp所管理的对象的成员函数和成员变量。
  • operator bool:用于判断sp对象是否为空,即所管理的指针是否为NULL。

wp模板类

  • 提供对象引用计数机制:通过wp,我们可以更方便地管理对象的引用计数,避免手动管理引用计数的繁琐和容易出错的问题。
  • 避免循环引用和内存泄漏:由于wp不会增加对象的引用计数,因此可以避免循环引用和内存泄漏的问题。
  • 提供对象缓存和访问控制:wp的使用可以帮助开发人员更好地管理对象的缓存和访问控制,从而提高系统性能和稳定性。

在wp的实现中,主要包含以下几个成员函数:

  • wp:构造函数,用于创建wp对象。
  • promote:将wp所管理的对象升级为sp对象。
  • clear:清空wp对象所管理的指针。

源码实现

RefBase

class RefBase
{
// ...protected:RefBase();
private:weakref_impl* const mRefs;
// ...
};

访问权限还是 protected,那么就说明,RefBase这个类只能用作基类。

RefBase::RefBase(): mRefs(new weakref_impl(this))
{
}RefBase::~RefBase()
{int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed);。。。//注释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 destructorif (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {// 释放记录引用计数的对象mRefs(weakref_impl类)delete mRefs;}} else {。。。//一些注释和打印}// 置空记录引用计数的对象mRefs(weakref_impl类)const_cast<weakref_impl*&>(mRefs) = nullptr;
}

RefBase 构造函数,只初始化了它的成员变量 mRefs 指针,而它被初始化为 weakref_impl 对象。

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;
...explicit weakref_impl(RefBase* base): mStrong(INITIAL_STRONG_VALUE), mWeak(0), mBase(base), mFlags(OBJECT_LIFETIME_STRONG){}
...
}

mStrong:代表强引用计数,初始值为 INITIAL_STRONG_VALUE = 1<<28

mWeak:代表弱引用计数

mBase:指向 RefBase 派生类对象

mFlags:代表 RefBase 派生类对象的生命周期

1、RefBase构建weakref_impl类,用于记录计数情况

2、初始化强引用计数为INITIAL_STRONG_VALUE,弱引用计数为0,默认强引用生命周期

//! Flags for extendObjectLifetime() 可以用extendObjectLifetime方法设置enum {OBJECT_LIFETIME_STRONG  = 0x0000,// 强引用生命周期OBJECT_LIFETIME_WEAK    = 0x0001,// 弱引用生命周期OBJECT_LIFETIME_MASK    = 0x0001 // 掩码,屏蔽或过滤二进制数据中的特定位};
强引用计数函数:incStrong、decStrong
void RefBase::incStrong(const void* id) const
{weakref_impl* const refs = mRefs; //mRefs就是RefBase在构造函数传进去的weakref_impl对象refs->incWeak(id);//弱引用增加,看下incWeak分析refs->addStrongRef(id);//空实现,用作调试,重点看宏定义DEBUG_REFS的开关//原子操作(保证多线程安全),记录强引用说计数mStrong,增加1,返回旧值,此时c=INITIAL_STRONG_VALUE。const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);....//如果强引用的旧值,不等于初始值INITIAL_STRONG_VALUE,那么代表现在的强引用计数为1,或2,或3,等等if (c != INITIAL_STRONG_VALUE)  {//直接return 掉,防止一直回调下面的onFirstRef()return;}...//当首次增加强引用时,原子操作mStrong.fetch_sub时,mStrong = mStrong - INITIAL_STRONG_VALUE = 1;int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);....//调用成员函数onFirstRef(如果派生类有重写该类,则会调用子类的onFirstRef)refs->mBase->onFirstRef();
}void RefBase::decStrong(const void* id) const
{weakref_impl* const refs = mRefs;refs->removeStrongRef(id);//空实现,用作调试,重点看宏定义DEBUG_REFS的开关//原子操作(保证多线程安全),记录强引用mStrong计数,减阖1,返回旧值const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);...//当强引用计数mStrong旧值为1时if (c == 1) {std::atomic_thread_fence(std::memory_order_acquire);//调用成员函数onLastStrongRefrefs->mBase->onLastStrongRef(id);int32_t flags = refs->mFlags.load(std::memory_order_relaxed);if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {//强引用生命周期(默认)时,释放RefBase对象(RefBase的派生类)delete this;// The destructor does not delete refs in this case.}}...refs->decWeak(id);//弱引用减少,decWeak
}

incStrong增加强引用计数,并第一次增加时(即在对象的第一次引用时被调用),回调onFirstRef

decStrong减少强引用计数,并最后一次减少时(即在对象的最后一个强引用被释放时被调用),回调onLastStrongRef

弱引用计数函数:incWeak、decWeak
void RefBase::weakref_type::incWeak(const void* id)
{weakref_impl* const impl = static_cast<weakref_impl*>(this);impl->addWeakRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试//原子操作(保证多线程安全),记录弱引用mWeak计数,增加1,返回旧值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);
}void RefBase::weakref_type::decWeak(const void* id)
{weakref_impl* const impl = static_cast<weakref_impl*>(this);impl->removeWeakRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试//原子操作(保证多线程安全),记录弱引用mWeak计数,减去1,返回旧值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);//条件1:如果是强引用生命周期(默认) if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {....//一些注释//条件2:强引用计数mStrong不等于初始值INITIAL_STRONG_VALUEif (impl->mStrong.load(std::memory_order_relaxed)== INITIAL_STRONG_VALUE) {....//一些注释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);//则释放记录引用计数的对象mRefs(weakref_impl)delete impl;}} else {// This is the OBJECT_LIFETIME_WEAK case. The last weak-reference// is gone, we can destroy the object.// 弱引用生命周期// 回调成员函数onLastWeakRef,并释放RefBase对象(派生类)impl->mBase->onLastWeakRef(id);delete impl->mBase;}
}

1、强引用计数的增加函数incStrong()->incWeak(),除了强引用计数mStrong加1外,弱引用计数也会mWeak也会加1

2、弱引用计数的增加函数decWeak(),只会单独对弱引用计数mWeak加1

强引用生命周期 弱引用生命周期
强引用计数mStrong为0 释放RefBase的派生类对象
弱引用计数mWeak为0 当强引用计数非初始值时,释放记录引用计数的对象mRefs(weakref_impl类) 释放RefBase对象和mRefs(weakref_impl类)对象

伪代码

decStrong(){1、delete this; // 即释放RefBase的派生类对象,mStrong=02、refs->decWeak(id) {//强引用生命周期if(mStrong !=INITIAL_STRONG_VALUE){delete impl; //当强引用计数非初始值时,释放mRefs(weakref_impl,负责记录引用计数的类)对象,mWeak=0}else{//弱引用生命周期//释放RefBase的派生类对象,调用RefBase的析构函数(调用delete mRefs:释放记录引用计数的对象mRefs(weakref_impl类))delete impl->mBase; }  }
}

3、当 RefBase 派生类对象处于强引用生命周期下,只有当强引用计数为0时,RefBase 派生类对象的动态内存才会补释放。

4、当 RefBase 派生类对象处于弱引用生命周期下,只有当弱引用计数为0时,RefBase 派生类对象的动态内存才会补释放。

sp模板类

//构造函数
template<typename T>
sp<T>::sp(T* other): m_ptr(other) {if (other) {check_not_on_stack(other);/* 调用RefBase类的incStrong函数:强引用计数mStrong加1,弱引用计数mWeak加1* 此时mStrong = 1,mWeak = 1.首次增加强引用计数,回调RefBase类成员函数onFirstRef*/other->incStrong(this);}
}            //析构函数
template<typename T>
sp<T>::~sp() {if (m_ptr) {/* 调用RefBase类的decStrong函数:强引用计数mStrong减1,弱引用计数mWeak减1* 此时mStrong = 0,mWeak = 0.强引用计数为0,回调RefBase类成员函数onLastStrongRef并释放RefBase对象.弱引用计数为0,释放mRefs对象*/m_ptr->decStrong(this);}
}

1、生命周期开始时:构造函数调用关联的RefBase对象的incStrong函数(强弱引用计数加1)
2、生命周期结束时:析构函数调用关联的RefBase对象的decStrong函数(强弱引用计数减1)

wp模板类

//构造函数
template<typename T>
wp<T>::wp(T* other): m_ptr(other)
{m_refs = other ? m_refs = other->createWeak(this) : nullptr;
}RefBase::weakref_type* RefBase::createWeak(const void* id) const
{mRefs->incWeak(id); /* 弱引用计数加1,此时mWeak = 1 */return mRefs; /* 返回记录引用计数对象mRefs */
}//析构函数
template<typename T>
wp<T>::~wp()
{if (m_ptr) m_refs->decWeak(this); /* 弱引用计数减1,此时mWeak = 0,释放mRefs对象 */
}//promote函数
template<typename T>
sp<T> wp<T>::promote() const
{sp<T> result;//判断wp<T>指向的引用m_ptr(T* m_ptr)是否被释放了,如果没有的话,将执行m_refs->attemptIncStrong(&result)if (m_ptr && m_refs->attemptIncStrong(&result)) {result.set_pointer(m_ptr);}return result;
}//attemptIncStrong:主要逻辑就是判断该对象是不是已经回收了,实际上只要是该对象没有被回收,那么都是可以被提升到强指针
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{//弱引用计数mWeak加1 incWeak(id);weakref_impl* const impl = static_cast<weakref_impl*>(this);int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);...//强引用计数mStrong大于0且不为初始值时while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {...//注释// 只有mStrong的值为curCount时,才会将其值修改为curCount + 1, return true,否则修改失败,return false。    if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,std::memory_order_relaxed)) {break;}...//注释}//之前强引用计数为0,或者为初始值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 releasedint32_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//如果强引用计数mStrong小于等于0if (curCount <= 0) {// the last strong-reference got released, the object cannot// be revived.//因此对弱引用计数mWeak减1(对应开头加1)并返回falsedecWeak(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 revivedif (!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.//弱生命周期时,mStrong加1并返回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) {//回调onLastStrongRefimpl->mBase->onLastStrongRef(id);}}}impl->addStrongRef(id);//空实现,重点看宏定义DEBUG_REFS的开关,用作调试#if PRINT_REFSALOGD("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;
}

1、生命周期开始时:构造函数调用关联的RefBase对象的createWeak函数(弱引用计数加1并返回对象mRefs).
2、生命周期结束时:析构函数调用关联的mRefs对象的decWeak函数(弱引用计数减1)
3、想使用关联对象时,需调用wp成员函数promote,得到sp对象,并且要对该sp对象进行非空判断.

Android framework RefBase,sp,wp相关推荐

  1. Android Framework学习(六)之RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  2. Android智能指针SP WP使用方法介绍

    Android手机操作系统既然是开源的操作系统.那么在具体的文件夹中就会存放着各种相关功能的开源代码.我们在使用的时候可以根据这些源代码进行相应的修改就能轻松的完成我们所需的功能.在这里大家就一起来看 ...

  3. Android Framework学习(八)之Handler消息机制(Native层)解析

    在深入解析Android中Handler消息机制一文中,我们学习了Handler消息机制的java层代码,这次我们来学习Handler消息机制的native层代码. 在Java层的消息处理机制中,Me ...

  4. android sp wp实例,android sp wp详解

    研究的时候,经常会遇到sp.wp的东西,网上一搜,原来是android封装了c++中对象回收机制. 说明: 1. 如果一个类想使用智能指针,那么必须满足下面两个条件: a. 该类是虚基类RefBase ...

  5. Android Framework中的线程Thread及它的threadLoop方法

    当初跟踪Camera的代码中的时候一直追到了HAL层,而在Framework中的代码看见了许许多多的Thread.它们普遍的特点就是有一个threadLoop方法.按照字面的意思应该是这个线程能够循环 ...

  6. 专题总纲目录 Android Framework 总纲

    专题总纲说明: 本系列文章虽说是 Android 的知识体系专题,同时也是学习Android Framework 系统的一个思路,尤其是当我们对Android 框架层 一点都不了解的时候,但前提是要有 ...

  7. Android C++的sp指针简介

    智能指针是c++ 中的一个概念,因为c++ 本身不具备垃圾回收机制,而且指针也不具备构造函数和析构函数,所以为了实现内存( 动态存储区) 的安全回收,必须对指针进行一层封装,而这个封装就是智能指针, ...

  8. Android Framework学习总结

    经过一段时间的学习,对于Android Framework大部分有一定的了解,现在将之前的学习进行总结并分类. 1.Android系统启动相关 Android系统SystemServer启动(上) A ...

  9. 如何调试Android Framework?

    Linus有一句名言广为人知:Read the fucking source code. 但其实,要深入理解某个软件.框架或者系统的工作原理,仅仅「看」代码是远远不够的.就拿Android Frame ...

最新文章

  1. poj3468 A Simple Problem with Integers
  2. MBR与GPT分区格式(实例-创建大于2TB的分区)
  3. python爬虫教程推荐-33个Python爬虫项目实战(推荐)
  4. node 生成随机头像_唯一ID生成算法剖析
  5. 对页面文章过长的处理方法
  6. C/C++二维数组名和二级指针的联系与区别
  7. C#利用反射将Datatable转化为指定实体类ListT
  8. 如何用Pygame写游戏(十四)
  9. d).关于steal lock
  10. 4. 根据UDP端口号抓IPsec协议默认的500/4500端口报文
  11. sublime text的插件emmet的功能介绍页
  12. 一图读懂开源协议_一张经典图,开源协议比较
  13. android lbs查询距离,不仅能搜索还能查信息 带你了解LBS应用
  14. 新疆计算机在线准考证打印,新疆2019年计算机准考证打印时间
  15. lisp6 暖通cad_这些高效插件,学CAD的基本用过两种以上
  16. Python-Level2-day04:正则表达式概述,元字符使用,匹配规则(特殊字符匹配,贪与非贪婪模式,分组),re模块使用
  17. usc week 5 计算几何(包含凸包) 队内练习题
  18. ASUS AC88U 路由器开机自启方法
  19. 基于Hexo和Github搭建博客
  20. ROS控制机械臂【2】:ros_control与实现

热门文章

  1. 分离轴定理及向量应用
  2. SQL Server 查询时显示行号
  3. Android开发中遇到mBluetoothAdapter.startDiscovery()搜索不到任何蓝牙设备
  4. RTduino+sht31温湿度传感器
  5. 利用fontforge制作自己的字体
  6. docker安装eclipse theia出现的问题
  7. 碳中和专利创新专题:各省市县专利面板(原始文件)、低碳专利授权数等多指标数据
  8. 2019年传统商家如何做社交新零售?
  9. AI×IoT时代打造未来家居,TCL智能新品必须加入购物车...
  10. [HSC-1th]web wp