LazyAn-—CocosCreator优化系列(三):内存优化

ps:本系列转载自大佬-BigBear023,为了方便日后学习,查阅和分享,现对系列文章重新进行整理、排版并对部分内容进行修改;如有不妥,请大佬联系我删除。原文链接:

https://blog.csdn.net/zzx023/article/details/88822815

  • 静态资源的内存管理

可参考官方文档:https://docs.cocos.com/creator/manual/zh/asset-workflow/scene-managing.html

静态资源指的是场景中直接或间接引用到的所有资源(脚本动态加载的资源不算在内)在场景资源的属性编辑器中可以勾选“自动释放资源”选项,从而在切换场景时,会自动将旧场景使用的静态资源释放掉,从而节省内存的占用

  • 动态资源的内存管理

动态资源的加载

动态资源统一使用cc.loader进行资源的加载以及管理。

可以使用的api:

cc.loader.loadcc.loader.loadRescc.loader.loadResArraycc.loader.loadResDir

要注意的一点是,CocosCreator中通过cc.loader去加载资源的所有方法,都是异步的,所以需要在回调中,确认加载完成后才能使用资源。也可以通过

cc.loader.getRes

这个api去同步的获取资源,但需要对get到的资源进行检查,如果没有加载或者没有加载完成,则需要等待或者通过cc.loader进行加载。

这样的话整个代码会清晰一些,避免掉入js的回调地狱中

例如:

通过简单的封装两个方法,在使用时可以保持代码的整洁易读

另外一点需要注意的是,当批量进行加载时,cc.loader也提供了onProgress回调,这个回调中的三个参数中

totalCount并不是指的是加载的资源总个数,而是加载这个资源所需要加载的依赖项个数。

比如加载一个SpriteFrame,它的totalCount就是3,这3个item分别为:jsontexture2DSpriteFrame

所以当totalCount为0时,并不是代表加载资源总个数为0,而是意味着这些资源已经加载过在内存中了,可以直接使用。

  • 动态资源的释放

动态资源的释放同样是通过cc.loader去管理的。

有两种释放资源的管理方式:

(1)自动释放资源

我们可以通过

cc.loader.setAutoReleasecc.loader.setAutoReleaseRecursively

来管理资源的自动释放设置

当场景切换时,由于资源已经释放,脚本中如果保留了引用,此时该引用将会变为非法引用。可以使用setAutoReleasesetAutoReleaseRecursively来保留这些资源。

setAutoReleaseRecursively指定资源及资源递归引用到的所有资源

默认情况下,当加载新场景时,旧场景的资源根据旧场景是否勾选“Auto Release Assets”,将会被释放或者保留。而使用 cc.loader.loadRes 或 cc.loader.loadResDir 动态加载的资源,则不受场景设置的影响,默认不自动释放。

使用这个 API 可以在单个资源上改变这个默认行为,强制在切换场景时保留或者释放指定资源。

(2)手动释放资源

cc.loader提供了以下的api,都可以去释放通过cc.loader加载进来的资源内存。

cc.loader.releasecc.loader.releaseRescc.loader.releaseAssetcc.loader.releaseAll

这里常用的是cc.loader.release

不推荐使用cc.loader.releaseAll

因为cc.loader.releaseAll会将所有通过cc.loader加载进来的动态资源全部释放掉,而在我们正常的项目开发过程中,基本上很少有场景没有使用到动态资源的情况,所以这种释放通常会带来程序的崩溃,因此使用上不推荐,最好不要使用。

cc.loader.release在释放资源时注意配合使用。

cc.loader.getDependsRecursively

例如在release一个prefab资源时,如果只是通过

cc.loader.release(this.prefab);

的话,这样只会release掉这个prefab所使用的json文件,而prefab所引用的spriteFrame以及其他的一些资源并不会释放掉,这样就有可能会造成内存的垃圾,长时间占用内存。

配合getDependsRecursively就可以正确的销毁掉prefab

在销毁prefab时也可以配合自动释放资源功能,将一些特殊资源保留在内存中,避免重复加载

  • 如何找到“垃圾”

随着游戏的运行,总会有一些内存是长时间不使用,同时又因为我们疏忽从而造成内存上的占用以及浪费。

通过google提供的snapshot以及Allocation Profile工具可以帮助我们找到这些垃圾

查找内存“垃圾”过程中需要注意的是:

  • 注意简单的对象创建,例如数组,{}

  • 注意不要忽略匿名函数

  • 注意匿名函数使用的外部变量将被匿名函数持有

  • 利用Timeline 观察 GC 调用频率

  • 寻找长期不释放的蓝色内存

  • 复用一切可复用的对象

       最后是内存使用的一个理念:复用一切可复用的对象

复用,并不仅仅是为了节省对象在alloc造成的开销,更重要的是避免GC时带来的额外开销。像一些战斗中的掉血数字,敌人的血槽,怪物,子弹,英雄头像等等,都是我们常常回去做复用的地方。

但还有一些地方我们不能忽略,比如:基础对象:cc.v2,cc.color 等

数组和对象 {}

对于常见一些复杂对象,我们可以使用对象池NodePool进行复用,对于基础的对象我们可以直接进行赋值从而达到复用的目的

参考引擎源码:

只有在不传入out的时候new新的对象出来,正常情况下的使用均是在原有的out上进行复用

var v1;v.add(cc.v2(5, 5), v1);//to do....v.add(cc.v2(10, 10), v1);//to do....

需要注意的是:注意闭包,注意复用时避免泄漏为全局变量

更多阅读:

CocosCreator优化系列(一):加载优化

CocosCreator优化系列(二):渲染优化

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值