浅谈Android引用计数(1)
16lz
2022-07-20
为了管理堆上的对象的生命周期,Android引入了引用计数和强弱指针。 假设有以下的场景: { classA{ };
A*p=newA(); //deletep; } 如果我们忘记使用deletep释放刚刚new出来的对象,就会发生内存泄漏。即使不会忘记释放,也会有一个问题:在什么时候去调用deletep?p可能在很多地方都在使用,如果一个地方使用完了就调用deletep,显然会对其他代码产生影响。这就提出了一个需求: (1)当p还在被使用就不能释放,当程序中没有地方使用p的时候就要释放掉这块内存。 如果仅仅是实现了这点还是不够的,因为如此一来,何时销毁P将会有限制(要考虑P是否还在被其他对象在使用),因此我们还希望有这样的一个功能, (2)只有一个对象管理p的释放,其他的地方都是保存着p的一个“引用”,每次想使用p的时候都必须探测一下p是否还存在,如果存在就可以使用。 为了实现以上目的,android设计了四个类:LightRefBase,RefBase,sp,wp。 LightRefBase实现了上文中的需求(1),为轻量级的引用基类,只支持强指针sp,RefBase实现了(1)和(2),同时支持sp和wp。 首先我们看下LightRefBase和sp的类图,图中TestObject是用户定义的测试类,继承了LightRefBase。 LightRefBase是一个模版类,保存着一个int型的引用计数,表示有多少个地方在使用T。函数incStrong用于增加引用计数,函数decStrong用于减少引用计数(在此函数中会检查引用计数,当引用计数为0的时候就会调用delete,释放TestObject)。sp也是一个模板类,其中有一个模板指针T,指向实际的对象。在本例中就是指向TestObject对象。 sp<TestObject>test=newTestObject(); sp重载了操作符”=”,在重载符中做了两件事情:
1.增加other的引用计数; 2.如果m_ptr不为空,就减少其引用计数,然后将other保存在m_ptr中。
A*p=newA(); //deletep; } 如果我们忘记使用deletep释放刚刚new出来的对象,就会发生内存泄漏。即使不会忘记释放,也会有一个问题:在什么时候去调用deletep?p可能在很多地方都在使用,如果一个地方使用完了就调用deletep,显然会对其他代码产生影响。这就提出了一个需求: (1)当p还在被使用就不能释放,当程序中没有地方使用p的时候就要释放掉这块内存。 如果仅仅是实现了这点还是不够的,因为如此一来,何时销毁P将会有限制(要考虑P是否还在被其他对象在使用),因此我们还希望有这样的一个功能, (2)只有一个对象管理p的释放,其他的地方都是保存着p的一个“引用”,每次想使用p的时候都必须探测一下p是否还存在,如果存在就可以使用。 为了实现以上目的,android设计了四个类:LightRefBase,RefBase,sp,wp。 LightRefBase实现了上文中的需求(1),为轻量级的引用基类,只支持强指针sp,RefBase实现了(1)和(2),同时支持sp和wp。 首先我们看下LightRefBase和sp的类图,图中TestObject是用户定义的测试类,继承了LightRefBase。 LightRefBase是一个模版类,保存着一个int型的引用计数,表示有多少个地方在使用T。函数incStrong用于增加引用计数,函数decStrong用于减少引用计数(在此函数中会检查引用计数,当引用计数为0的时候就会调用delete,释放TestObject)。sp也是一个模板类,其中有一个模板指针T,指向实际的对象。在本例中就是指向TestObject对象。 sp<TestObject>test=newTestObject(); sp重载了操作符”=”,在重载符中做了两件事情:
1.增加other的引用计数; 2.如果m_ptr不为空,就减少其引用计数,然后将other保存在m_ptr中。
当过了sp的作用域,sp就会被析构: 当过了sp的作用域,sp就会被析构,在析构函数中会调用m_ptr的函数decStrong减少计数。
- template<typenameT>
- sp<T>&sp<T>::operator=(T*other)
- {
- if(other)other->incStrong(this);
- if(m_ptr)m_ptr->decStrong(this);
- m_ptr=other;
- return*this;
- }
每次减少m_ptr的引用计数的时候,最终都会调用LightRefBase的decStrong,检查引用计数是否为0,如果是,就会删除我们new出来的TestObject。 轻量级的引用和sp指针结合就实现了对堆上分配对象的生命周期的自动管理。只要这个对象还有地方在使用就不会释放,一旦引用计数为0,没人使用了,就会被delete。
- template<typenameT>
- sp<T>::~sp()
- {
- if(m_ptr)m_ptr->decStrong(this);
- }
本文出自 “HelloWord” 博客,谢绝转载!
更多相关文章
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- android 使用html5作布局文件: webview跟javascript交互
- Android(安卓)Resource介绍和使用
- "Failed to fetch URL https://dl-ssl.google.com/android/repos
- 使用NetBeans搭建Android开发环境
- android 零星调试笔记