cocos creator cc.instantiate内存 不能被清理调

使用cocos creator 开发小游戏的排行榜时,初始化scrollview时,调用cc.instantiate初始化 节点之后,退出界面,调了各种释放资源和gc,但是在手机微信上内存一直没有减少,而且每次进去排行榜退出时,内存就增加几十上百兆,且一直不会减少,持续增加,而在浏览器和微信开发工具中,一进一出内存变化很少.求解…

同样遇到这样的问题,目前用croator发布的微信小游戏,android手机运行打开调试,发现内存一直上涨,直接游戏闪退。引擎大爷麻烦速度看下。

麻烦给个demo,我这边测试过,没法复现。

怎么给你,扫码可以?我开发版本1.9.2

怎么联系你,很容易测试的!建议用android手机测试,不要用ios的

做个工程项目给我,我要实际分析的,上传一下附件。

测试前

多次点击后

发布微信小游戏,安卓手机打开这个性能数据,每次点击都会新增内存,销毁不释放。
如果不明显,可进行疯狂测试,或是去代码里把实例化的个数改大点。

代码如上

有没有在看啊,什么时候能给个结果,项目要上线了,等了不我就换引擎了…


算了,算我求你了,加个班速度解决吧,项目再拖策划和老大锅要全扔给我了,bug已帮你定位到这个地步了

我周末抽空看下,这个问题可能跟微信环境有关系,因为在浏览器上无法重现,只能在微信环境重现,但是微信环境无法调试,所以很蛋疼,我周末给你回复吧

1赞

事实不是这样,说这样的话,请拿出依据,否则你说爽了,对其他人和引擎团队的影响是很负面的,这样的激将法来博取我们的关注也跟我们免费开放得服务于社区的目的完全相悖。


澄清完说说你遇到的问题,我分别用 2.0 和 1.9.3 测试你的项目,在华为 P20 上的表现的都是接近的,在多次添加之后,业务内存和总内存都有不同程度的增加,绝大多数时候不明显,偶尔有接近 10 mb 左右的增加,没有规律。我尝试添加了下面的代码:

    cc.director.on(cc.Director.EVENT_BEFORE_VISIT, function () {
        wx.triggerGC();
    });

之后内存相对稳定一些,但是也有细微的增加。
最后做了一个尝试,验证了我的想法,在内存相对增加一些之后,我尝试

  1. 退出小游戏,再进入
  2. 锁屏,再解锁

内存都会回归到最初的状态。

结论就是这些内存的增加完全是微信层的垃圾回收控制以及绑定层导致的,并且可以被回收。


提醒一下你的测试例问题:

  1. 并不是说你把一个节点命名为 testPrefab 它就是 prefab 了,他仍然只是一个节点,cc.instantiate 虽然可以得到结果,但我们不建议这样做,从 API 描述 你可以看到,这样是在 clone 这个节点,并不是真正的实例化 prefab,prefab 是一种资源,是可以被反序列化机制实例化的一种资源,这类操作都不应该直接 instantiate node,而是应该拖拽节点创建 prefab,然后代码中 instantiate prefab

  2. 你的测试例确实过于简单,有可能你的项目中遇到的问题并没有体现在这个测试例中,这点我就无从得知了。

2赞

喂喂喂,我们用creator 1.9.2都开发了5个微信小游戏了,并没有闪退。
说问题就说问题,别这么口无遮拦的

所以你的结论是微信在导致内存在不断升高……

另外对于cocos creator 的评价我先道歉,项目出现这样的问题我很着急,急于将这样的锅扣在cocos头上显然是不对的……同时也对于引擎团队在这种免费项目中作出的努力表示致敬,特别是周末还在加班处理这样的问题……

再说一点,对于你说的测试例中的问题,我说明一下,你建议生成prefab,不要去clone节点,我不敢认同……

实际项目中,这种情况可能无法避免,其中一个原因就是节约资源个数的需要,每多一个prefab在import里就多一个文件,有些项目资源文件过多,导致这里的文件数量越来越多,热更时严重影响下载时间……所以实际开发中很多独立使用的需要clone的,就直接放到节点中clone,当然这个问题也可以通过压缩import资源目录去解决。我想说的是案例中的clone仅是用户习惯问题……

回归到内存不断升高的问题,其实cocos用户和开发团队在这种问题上的目标是一致的,那就是解决问题,目前不管微信社区还是cocos社区都有人反馈这样的问题,且测试结果都证明了内存问题确实存在……我也不希望这个帖子成为无意义的口水争斗,但求有个明确的解决方案… 后面我去微信方面看看……

从你提供的测试例情况来看是这样的

实际上你放在场景中,跟放在 prefab 中也是一样的节点结构,把节点放在 prefab 中(从场景中移除),需要的时候再 instantiate 本质上加载的数据并没有更多。当然文件数量可能会多一些,但我们也有合并 json 的打包选项。我跟你解释的是 instantiate 一个 Node 和一个 prefab 机制是不同的。

当然,我们需要的是明确可以复现问题的方法,从上面你给的案例中来看,只要是微信在底层处理的内存,引擎是无法触及的,引擎和开发者只能够依赖于 JS 的垃圾回收机制。

当然了,有一些已知的用法问题我也可以提一下:有些用户在使用了 prefab 之后,想通过手动释放来清除内存,可能后面又重新用到,想要重新加载。逻辑上这没问题,但很容易掉坑,比如你的 prefab 和它依赖的所有资源是否彻底从 loader 中清空了?如果清空了,节点树中是否还存在某些对已释放贴图的引用?如果节点树中还存在对旧贴图的引用,那么这个对象是不会被垃圾回收机制回收的(因为还有引用),那么这个时候重新加载的时候,发现 loader 中已经不包含旧的资源,就会重新加载,导致内存变得比完全不释放还高,并且重复加载释放越多次,内存越高。这些问题是需要在游戏管理资源的时候考虑的

1赞

你这个性能数据中的具体数据是怎样获取到的、能传授一下不:grin:

目前我这边游戏中在不切场景前资源没有作手动释放……应该不会是资源重复加载的问题……给你的测试例中也没有手动释放,测试项目中内存升得较慢,实际项目中上升非常快,微信内存稳稳的只升不降,自己做过更多尝试,包括调用微信的回收API,所以我觉得这个问题可能只有微信能解决……或是,能否麻烦开发团队与微信开发就这个问题对接下,能更快的引起他们的重视……

微信留意到这个问题了,但是他们也还没有定位问题,目前收到的都是非常模糊的描述,很难确定原因是什么,能不能做一个可以真正重现内存只升不降,增长比较明显的例子

1赞

我给的示例放大100倍不行么,不然就放大更多,实在不行我就上我的项目阉割版…我不在公司,今天是纯手机回复的,周一我再跟进给你

1.给的示例能说明问题,将示例代码里的max改大点,我这里改为1000后,随便点过7-8次后,内存上升近100M,业务内存明显上升60M左右,随后不会下降。
再多次疯狂测试后,内存上升到一定高度部分手机闪退。

2.同时发现,如果测试中断,比如测试一半,业务内存由170升到250左右(中间点击过近20次),待机或切入后台,回来时,内存有明显下降接近回归正常

3.我另外把max改成100,也就是降低了10倍,但同时在被clone的节点上挂了个动画文件,clone后,播放这个动画文件,内存上升更加明显,也就是说内存上升明显的程度可能与资源的个数有关。