您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x中的内存管理机制

2016-05-18 09:37 507 查看
首先说,程序中的内存管理很重要,否则程序死掉,bug。

C++中的内存管理机制。

堆(动态变量)

栈(局部变量)

全局区(全局变量/静态变量)

常量区(常量)

代码段

堆(动态变量):特点

用new操作符在堆上开辟内存空间。

优点:C++使用者可以控制数据的生命周期,即使数据是在

函数中创建的,离开该函数,开辟的堆内存依旧存在。

缺点:指针使用不当,容易造成内存泄漏。

野指针:指针A所指向的内存已经被释放,

该区域内存已经重新分配给其它的指针B。

此时指针A在程序中已经不起作用,但是你贸然的

用指针A继续操作该片内存,就会发生异常。

举个好玩的例子: 你到餐馆去吃饭,店主给你随机分配了一个漂亮的碟子,但是你实在是太爱它了,当你用完餐之后,该碟子被服务员带走洗刷。你此刻在餐馆休息片刻,这时另一个人也来吃饭,店主很巧合的把这个碟子分配给这位客人使用,你不甘心,你上去就夺客人手里的碟子。此刻的后果就是,客人会骂你是傻逼吧。呵呵。 你没有权利使用了,你就是野指针。【注意:现在的规则是一个人只能用一次】

重复释放:两个指针同时指向一块内存,如果每个指针都释放一次,

一个指针释放两次,都会造成一块内存释放多次的操作,程序就会出问题。

内存泄漏:

new了一块堆空间,你使用完毕之后,没有回收该内存。本来内存都是有限的,

如果其他的程序内存不够用了,就会暂停程序,报错。

栈(局部变量):特点

局部变量一般创建在函数中,存储在栈中,当局部变量被创建的时候,

进行压栈操作,作用域为从函数的定义到函数的结束。

当函数结束的时候,按照顺序进行出栈操作。

优点:函数结束,局部变量的生命周期结束,无须使用者控制生命周期

缺点:使用者无法控制数据的生命周期。

智能指针:(动态变量和局部变量的完美结合)

智能指针分类:

shared_ptr指针: 定义方式:shared_ptr up1(new int(5));

可以与其它的智能指针共享内存,采用引用计数的方式管理内存。

只有当所有的指针都执行reset函数,或者离开作用域的时候,才会真正的释放内存。

weak_ptr指针:定义方式 weak_ptr up2=up1;

可以指向shared_ptr的内存,但是不拥有该内存,通过其lock

成员访问该内存,当该内存无效的时候,返回nullptr,常用于验证shared_ptr指针的有效性。使用指针的时候,最好使用weak_ptr来间接访问内存。

unique_ptr指针: 定义方式:unique_ptr up3(new int(5));

不能与其它的智能指针共享内存,如果运行

unique_ptr up4=up3; 编译的时候,会报错。可以通过move函数转移内存的使用所有权,一旦转移成功,原先的unique_ptr就失去了对内存的所有权。再使用的话会报错。

通过*up3访问这块内存块,退出函数或者执行变量的reset函数的时候,会释放内存。

好了,先总结一个智能指针,智能指针就是 “局部变量” 和 "动态变量" 的结合。利用智能指针“局部变量”的好处,达到操作和控制"动态变量的目的"。

特点: shared_ptr,可以多个shaed_ptr指向同一块内存;

weak_ptr,不拥有该内存,但是可以间接访问;

unique_ptr,只能一个智能指针对应一个动态变量,但是可以通过move转移动态变量的所有权。

智能指针的缺点:

shared_ptr  为了保证线程安全,加入了互斥锁,互斥锁对性能会有影响。

创建shared_ptr需要显示声明智能指针,编写代码的时候注意事项很多。

Cocos2d-x 内存管理机制中的引用计数。

Ref类是所有类的基类。

而这个Ref类具有内存管理机制,它的主要功能就是

使用引用计数的方式,控制元素的内存管理。

Ref::retain(); //用于增加对象的引用计数。

Ref::release();用于减少对象的引用计数。

Ref对象创建的时候,在构造函数中,将引用计数设置为1.执行一次retain操纵,引用计数为2,执行一次release,引用计数为1,当引用计数为0的时候,delete。

AutoreleasePool类用于对Ref元素进行批量的引用计数控制。

Ref::autorelease();//将Ref对象加入到AutoreleasePool实例对象

AutoreleasePool::addObject(Ref* object);//将Ref对象加入到AutoreleasePool对象。

AutoreleasePool::clear();//将已加入AutoreleasePool对象的Ref对象,进行release操作,并将与AutoreleasePool对象有关联的Ref对象全部与该AutoreleasePool取消关联。

Cocos2d-x 内存管理机制中的智能指针

"智能指针"  Cocos2d-x 自带的autoreleasepool对象,当一个Ref对象被创建的时候,引用计数为1.将其加入到AutoReleasePool后,当一帧结束的时候,AutoReleasePool执行clear操做,Ref对象引用计数减1后为0,delete。

如果该Ref对象,在一帧结束之前,做了影响引用计数的操作,导致Ref对象的引用计数大于1,那么在一帧结束的时候,引用计数减1,而不会被delete。

为了简化代码,Cocos2d-x将Ref对象的new和autorelease函数包装成了

一个函数,create。元素直接执行create函数,就完成了创建并加入到了autoreleasepool中。

PoolManager类

PoolManager是AutoreleasePool实例对象的管理者,

每个Cocos2d-x程序只能由一个PooManager对象。

每个AutoreleasePool实例对象在创建之后,就要被push到

这个PoolManager对象的_releasePoolStack成员变量中。

PoolManager::push()和PoolManager::pop()用于对PoolManager对象关联的

AutoreleasePool实例对象进行添加和删除操作。

同时也改变了PoolManager的当前AutoreleasePool实例对象。

PoolManager::getCurrentPool();//得到当前的AutoReleasePool对象。

在AutoReleasePool的构造函数中,将AutoReleasePool实例对象加入到PoolManager;

在析构函数中,将AutoReleasePool实例对象进行clear,并从PoolManager移除。






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: