《Cocos2d-x 高级开发教程》读书笔记1:内存管理
现有智能内存管理技术
- 引用计数
可以说这种方法使用还是比较广泛,之前在读android源码时也发现是使用这种方法。其原理理解下来就是在系统的基类中添加一个引用变量,当继承该基类的实例被开辟时,则引用计数变量+1,当释放时如果引用计数-1等于零时,说明该对象生命周期结束,可以安全释放资源。
书中提到,该方法的优点:维护引用计数比维护生命周期信息轻松很多,将new和delete转换成了使用和使用结束的事件。
缺点:堆碎片和管理烦琐依然存在。
- 垃圾回收
最有名的垃圾回收机制应该就是Java中的垃圾回收。
优点:将程序员从复杂的内存管理中全完解放,防止内存泄露,有效的使用内存
缺点:通常作为一个单独的低级别线程运行,不能手动指派垃圾回收器回收某个对象,也就是说缺少灵活性。
Cocos2d-x中使用的内存管理
- 其重点分为两点:引用计数和自动回收(autorelease)
Cocos2d-x来源于Cocos2d-iphone,所以与objective-c一样,也采用引用计数和自动回收的机制。
Cocos2d-x的根类为CCObject,所有类都派生于该类。在该类中实现了引用计数机制,实现了几个比较重要的API:
unsigned int retainCount(void) ; //获取当前引用计数的值
void retain(void); // 引用计数值+1
void release(void); // 引用计数值-1
CCObject *autorelease(void); // 将对象放入自动回收池
- 自动回收池的几个特点:
1. 可以手动创建和释放
2. 可以嵌套
3. 当回收池自身被释放时,对池中所有对象执行一次release()方法
4. 引擎在每次游戏循环开始前会建立一个回收池,并在每一帧结束时,池中对象也都会执行一次release()方法
所以说当执行autorelease()方法时,并不会像release()方法一样马上将引用计数值-1,而是和该对象执行autorelease后所加入的回收池的生命周期密切相关。
- 如何创建和释放回收池
通过调用CCPoolManager->push()和CCPoolManager->pop()两个方法。之所以使用push和pop两个单词,也是因为回收池内部排列成栈的原因所致,只有在栈顶的回收池才能加收对象的加入。
CCPoolManager::sharedPoolManager()->push(); //push一个回收池,也可以说是添加一个回收池
.......... // 各种创建对象后调用autorelease方法
CCPoolManager::sharedPoolManager()->pop() // 销毁刚才调用push方法创建的回收池,因为是栈类型,也只能销毁最近一次调用push方法创建的回收池。此外也销毁所以池中对象,也就是那些在push与pop之间调用autorelease的对象。
- autorelease优缺点:
优点:在有些时候无法直接调用release释放,如在工厂模式中,此时非常适合使用autorelease
缺点:
1. 池中对象过多会导致资源紧张
2. 如autorelease时出现错误则难以调试
所以尽量使用release方法而在一些必要时候才使用autorelease方法
- 另外几个结论:
1. 对象传值时,应考虑新旧对象相同的特殊情况
2. 工厂方法返回前,应调用autorelease方法
附:
Cocos2d-x提供内存相关的一些宏在"platform/CCPlatformMacros.h"中:
仅举例两个应该是常用的:
CC_SAFE_RELEASE(p);// 释放p对象,如果已经为null则不做处理
CC_SAFE_RELEASE_NULL(p);// 释放p对象,释放后至为null,如果已经为null也不做处理
---------------------------------------------------------------------------------------------------------------------
该文是读书笔记,包含自己的一些见地,如有错误欢迎评论或加QQ或微信指正交流:QQ/WeChat:263113565