Cocos2dx 3.4内存管理机制——autorelease

前端之家收集整理的这篇文章主要介绍了Cocos2dx 3.4内存管理机制——autorelease前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.C++内存管理机制:显式堆内存管理

内容:使用newdelete动态分配与释放堆上的内存

—缺点:(1)野指针——被释放的内存仍然被某一指针所指向

2)重复释放——对指向同一内存的两个不同指针分别释放,或同一内存释放两次

3)内存泄露——不使用delete释放内存

2.C++11内存管理机制:智能指针

内容:智能指针试图将一个动态分配的内存单元与一个自动变量关联,让这个自动变量在离开代码块并被自动释放的时候释放其所管理指针的内存单元

—类型:(1unique_ptr:独享分配的内存,不能与其他智能指针共享内存

2shared_ptr:可以通过引用计数的形式共享同一内存,引用计数为0时才会释 放堆内存

3weak_ptr:通常通过使用lock成员来访问其指向内存的一个shared_ptr对象, 用于验证shared_ptr的有效性

—缺点:(1性能低:shared_ptr为了保证线程的安全,必须使用一定形式的互斥锁

2)使用不便:显示声明智能指针,需要引用的地方一般使用weak_ptr指针,否 则在node移除时需要手动减少shared_ptr指针的引用计数

3.垃圾回收机制

—基于引用计数

—基于跟踪处理:先产生跟踪对象的关系图,从根对象开始查找他们引用的堆空间,并在堆空间上做标记,做完标记之后,所有未被标记的对象即被视作垃圾,在第二阶段被清理,清理方法是对正在使用的对象进行移动或者复制,从而减少内存碎片的产生。

4.Cocos2dx内存管理机制

内容

(1)引用计数:2dx所有对象都继承自Ref基类,Ref基类主要职责就是对对象进 行引用计数管理

(2)“智能指针”:C++11中的智能指针是将动态内存与自动变量进行绑定,自动变量释放时则动态内存亦被释放,而2dx的管理方式与之也有异曲同工之妙,2dx并不是绑定自动变量,而是将对象通过autorelease()方法放入AutoreleasePoolAutoreleasePool可看做存储调用autorelease()方法对象的容器,该容器在每一帧结束时都会对容器内的对象进行一次release()操作,若对象创建后,未被引用,则分配的内存会被release(),进而引用计数为0,动态内存被释放,而有被引用的对象则其引用计数不为0,其内存继续存在,对每一个对象release()结束后,AutoreleasePool就会把容器内的对象清空,这样引用计数不为0的对象,再被引用对象移除引用关系后就会自动释放内存。

PSRef基类主要职责就是对对象进行引用计数管理

5.自定义AutoreleasePool队列

—问题描述:对一些游戏对象来说,一帧的生命周期显然有些长。举个例子:一帧中调用100方法,每个方法创建10autorelease对象,这些对象都没有被调用,只在每个方法的作用域内被使用,这样,在一帧结束的时候,内存中的峰值为1000个游戏对象所占用的内存,而实际上,如果autorelease对象不是在每一帧结束时被清理,而是在需要清理的时候被清理(例如方法结束时),那么每帧内存的峰值也就是10个对象的内存,那么如何解决呢?

解决方法:上述问题产生的原因是autorelease对象只有在每一帧结束时才能被清理,不能在需要的时候被清理,那么如何才能让autorelease对象在需要被清理的时候被清理呢?答案就是使用自定义autoreleasePool自定义autoreleasePool就是一个自动变量,他的构造函数autoreleasePool分配大小,并将其假如PoolManager,他的析构函数则清除autoreleasePool,并将其从PoolManager中弹出,那么只要自定义autoreleasePool的生命周期结束,那么在autoreleasePool中的对象都将被释放一次,解决了必须等一帧结束才能释放autoreleasePool中对象的问题。

—例子:

voidcustomAutoreleasePool()

{

AutoreleasePoolpool;

Autoref1=CCSprite::creare();

Autoref2=CCSprite::creare();

}//方法结束后,pool中的对象都将被释放

6.PoolManagerAutoreleasePool队列的工作流程

—第一次创建:当第一个Autorelease对象创建时会调用PoolManager::getInstance()->getCurrentPool()->addObject(this);本句可分为三部分,第一部分为PoolManager::getInstance(),创建PoolManager实例,外加创建第一个AutoreleasePool队列,也就是默认的AutoreleasePool队列,由于AutoreleasePool的构造函数中将其添加PoolManager,因此默认的AutoreleasePool队列也就是CurrentPool,因此第二部分getCurrentPool()也就是获取默认的AutoreleasePool队列,第三部分也就是将Autorelease对象添加到默认的AutoreleasePool队列,此部分叙述了PoolManager、默认的AutoreleasePool的创建。

—每一帧结束的对象清理:在游戏每一帧结束后,会调用PoolManager::getInstance()->getCurrentPool()->clear();

该句主要是获取当前的AutoreleasePool进行clearclear内容无非是对AutoreleasePool中的对象进行release,然后再将AutoreleasePool中的所有对象清除

PoolManager的释放:PoolManager的释放是在游戏结束后,游戏实例被释放时释放的,释放时调用PoolManager::destroyInstance();主要是移除了PoolManager实例,同时在其析构函数中,顺带把其在_releasePoolStackautoreleasePool对象同时移除

原文链接:https://www.f2er.com/cocos2dx/343869.html

猜你在找的Cocos2d-x相关文章