cocoscreator 场景切换内存泄漏

cocoscreator运行版本:1.4.2 和1.5.0-beta3.2
运行平台:ios
游戏设计分辨率:1080x1920
主要问题:两个场景频繁切换,内存一直上涨不下降。游戏中的场景并未使用cc.loader 手动加载资源的前提下,每次切换涨几十兆,来回几十次场景切换,真机中就崩溃了。但是模拟器中不会崩,因为电脑的内存够大。

测试方式:使用1.5.0版本创建新的demo,两个场景切换,发生内存泄漏,真机调试,instruments详细见截图:
demo刚启动进入场景发生的泄漏和内存见图(1)


instruments 测试 jsb 是不准确的,因为 js 引擎堆中的内存是由 js vm 管理的,这个 snapshot 有时候会误报。

NewDemo.zip (611.3 KB)
我上传了一份demo,使用的是1.5.0 创建的demo,我在scene1 和scene2 中来回不停切换,大概几十次来回,在真机中就发生了崩溃,demo中只用到了一张背景图和两个按钮。如果没有发生内存泄漏 怎么会崩溃啦。。。。

@zilong 谢谢你的回复

你用的是 1.5.0 beta3 吧? 我试一下你的这个 demo。

@zilong 是的,1.4.2 和1.5.0 beta3 都有这个问题,麻烦帮看看是什么原因造成的,感谢

再怎么误报,楼主增长的内存和崩溃不是假的吧?

这个论坛每次来看一眼都有吐槽内存泄露的,真是好奇林顺他们追求了几年的『去掉retain/release』到底做了什么。

看图中主要的泄漏应该是 arguments object,在当前的 Spidermonkey 版本中,只要在函数中使用 arguments,不管怎么用,都会泄漏这个对象。我们检查下你的项目再说

麻烦各位大神了,我们游戏正等着上线啦,现在频繁切换场景就会发生内存增涨崩溃

因为现在 c++对象是由 js 对象来管理生命周期的,而你的测试场景 js 对象很少,js heap 还没有达到 GC 的条件。所以 native 对象的内存一直没有被释放。

你需要在 loadScene 之后,手动调用 cc.sys.garbageCollect(); 方法。

你在两个 loadScene 之后都调用 cc.sys.garbageCollect(); 就好了。

1赞

另外,你的例子中的使用方式是有问题的,需要频繁切换的场景,不应该勾选 auto release,这样频繁得销毁,加载场景以及资源消耗是很大的

1赞

我使用过cc.sys.garbageCollect(), 这个调用后,在iOS 真机中容易发生崩溃。而且就是我发给你们的这个demo,在iphone 5s 中,频繁切换场景中,都会发生崩溃。并且发生了内存不足报警,证明已经达到gc 条件,native对象无法释放。证明引擎确实发生了内存泄漏,就添加一张图片都会崩溃,不敢大规模使用游戏贴图了。同时,instruments 中每次切换场景都有几千个内存泄漏提示。

谢谢你的回复,我也是这样想的 频繁切换的场景不用勾选,但是我实际测试发现,就算我没有勾选,同样发生了泄漏,内存同样不足发生了崩溃,只是时间问题。其实有个办法就是 使用触摸精灵之类的工具,不停的模拟屏幕点击,很快就会发生崩溃。如果你们无法在引擎级别上修复,我也只能另外想办法了

使用 cc.sys.garbageCollect() 之后的崩溃调用栈麻烦发出来看一下,我们没有观察到崩溃的现象。

现在的内存模型的确有一个问题,就是没有根据 C++ 内存使用情况主动去清理 JS 层内存,导致 JS heap 不够高,但是实际内存使用已经很高,所以 GC 没有触发,但是实际内存过高导致崩溃,这个问题是可以被解决的,我们在 1.6 中会修复。

所以目前才给出主动在场景切换中调用 cc.sys.garbageCollect() 这样的解决方案。

没有勾选 auto release 的情况下,每次切换场景会从 scene asset 创建一个场景出来,所以会有对象的创建,比如 label, node, component 等,这是你观察到的内存的增长,也是可以被 cc.sys.garbageCollect() 所回收掉的,在 loadScene 之后调用 GC 后,我们观察到的内存曲线是平的,没有出现持续增长的情况。

Instrument leak 工具所检查到的 leak 的确有,但是没有几千个这么多,每次场景切换几十个,实际占用的内存也不高,我们看了一下 leak 的对象信息,都是 Spidermonkey 的 malloc 内存块,我们目前无法确定是 Spidermonkey 的内部机制导致的还是什么原因导致的。

很久之前遇到过 后来发现 是cocos molliza库的问题 你看他们是不是又更新 mozzila了 建议用老版本试一下

cocos2d-x 用3.11 3.12版本试试 现在看不到他们每次版本的更新内容了

我这边的测试结果来看, cc.sys.garbageCollect() 并没有导致崩溃,不过我使用的不是 iphone 5s

这是解决了还是没解决呢?

我之前使用cc.sys.garbageCollect() 也要崩溃,后来发现是我自己的Native代码里主动释放了Native对象,调用cc.sys.garbageCollect() 的时候js层再来释放,就崩溃了。

群号397902551讨论cocos