Cocos致命缺陷,浏览器超128M空间崩溃,白屏,花屏

不是标题党啊,是真事儿。
请听我伟伟,道来:

  • Creator 版本:3.8.2

  • 目标平台:谷歌浏览器 中的WEB游戏形式

  • 重现方式:
    问题1。不会自动释放内存。在类成声明一个数组,再一个循环中对这个数组添加 instance方法生成的节点对象,在循环的最后将这个数组成员用 =[] ,和 .lenth=0来清空它,接着再次循环。
    就这样,内存会占用越来越大,直到崩溃。
    问题2。只能用到128M空间,再多崩溃,白屏,花屏。我是说在浏览器里。

  • 重现概率: 目前 100%

这不应该啊,不科学啊。我怎么也想不通Cocos这么好的游戏引擎怎么会有这样的致命缺陷!
有什么方法可以解决以上2点问题吗?
谢谢!

https://docs.cocos.com/creator/3.8/manual/zh/scripting/create-destroy.html#销毁节点

1赞

节点创建了不销毁的吗

感谢各位的解答,我会关注这里的进展的,我在用各位说的方法去试,看能不能解决问题。
谢谢!!

数组清空了有什么用, 节点的本体还存在。。

没错啊,问题依然还存在!

还是不行啊,问题依然还存在,现在我把挂有instantiate()方法生成的节点的父节点应用了 .destroyAllChildren() 方法,
可是,但可是,还是会崩啊,是不是在子节点上我用instantiate()一样生成的实例,不会一起销毁啊?
我查了整个代码能应用此方法的都用了,还是会崩溃或白屏,
会不会COCOS 还可以设置一下程序运行的空间?我发现现在只要超过128M就一定会崩。
这个有趣的(烦人)的问题要怎么解决?希望高手们踊跃支招,我会把最终方法发出来一起学习的,谢谢!

如果你已经代码里面释放了节点,但是还有内存增加的情况,你可以先从4个地方查一下
1.是不是另外无关的地方导致的,不是你这里的代码导致的? 验证方式就是注释掉你这个数组对应的代码,看看还会不会内存增长
2.是不是你实例化的节点,本身挂有一些脚本或者其他东西,导致内存没释放。验证方式就是用空节点来尝试。
3.是不是你释放的方式有问题,例如父节点选错了,或者在整个代码结束的时候才destroy。这个就要你自己查代码了。
4.到底创建销毁了多少个节点,要统计好,不能脱离数量来谈,循环本身跑的很快,难保数量就比较大,例如一百万个节点才出现,那一般游戏就没什么问题了。
只有排查了这些,才能说cocos节点本身可能的问题。

另外128M这个数据你从哪个地方看到的? 是web 开发者工具里面的memory选项卡中的堆内存?我从来没遇到过这个限制,300m都没啥问题的。可能是你看的地方不对,例如你看的任务管理器里面进程占用的内存,那可能看错成其他进程,或者显示不对也有可能。

1赞

感谢回答,
我排查了一下,针对您给的方法我一一回复:
1,最后再考虑这样做,因为,我就是我找到问题在哪,不是想找怎么没有问题。
2,的确在子节点上挂有别的预制体还带有一些脚本,这些预制体也正是实例化时用到的模板类,我想您能懂我说的意思 如const gameObjPrefab1 = instantiate(this.pfb_item1);,但这不应该成为不释放的原因,因为只要父节点标记释放,那都应该一起放掉.
3,父节点我特意用类成员变量保存,不会有错,而且都已被.destroyAllChildren()标记释放。
4,子节点数量在500个以内,并且是游戏开闭局多次后才崩溃的,也就是循环里是没有问题,问题出在不被释放。
5,128是在开发者工具中的menory中看到的,它只要过128就崩溃。

遇事不决上demo~

1.不是指的让你注释掉让程序没有问题,而是这点是首先确定是这个循环引起的,而不是其他地方引起的,如果找了半天,发现不是这段代码引起的就白找了。
2.子节点这里,不是说放进去不释放,而是怀疑你子节点上面挂的脚本本身有问题,例如你子节点上有一个组件,这个组件创建了一个纹理,并且没有释放这个纹理。那么就算这个子节点被销毁了,那么那个纹理也不会被销毁。所以让你用空节点试试看。
5.128这个确实我没碰到过,我300-400m都没问题,所以怀疑是你哪里纹理没释放造成显存过大,而显存那部分是在这个memory里面看不到的。

从你的描述,你应该是没有调用过destroy的~

  1. 你instantiate之后的节点,也没有设置为父节点的子节点,如果没有,那么你调用destroyAllChildren是没有用的
  2. 你把节点赋给一个数组,通过数组的方法去清除,那就更没用了。

hehehe : )

COCOS的操作要这么细么?我以为,只要销毁挂载节点那如纹理 texture2d这样的东西也会自然释放,不是这样的吗?那COCOS要操作的东西可太多了,是不是很繁琐?

您的回复有很高的参考价值,只是在本例中已经通过 .parent()方法设置了父节点,所以呢1点应该是起作用的,2没有意见,我清空了,又做了父节点上的destroyAllChildren(),来重置。还是不太对啊,现在大家的意见是建议我做DEMO测试一下结构,我正在考虑。

是的,所以可以自己根据引擎提供的addRef和decRef设计一套跟随节点生命周期的资源管理方案,论坛也有很多资源管理方案你可以参考一下

感谢回复我的问题,我会继续找答案的

js的回收机制导致引擎设计了引用计数的方式来管理资源,销毁节点并不会自动释放依赖的资源需要你自己管理

感谢回复,现在我问题是由于我初学COCOS,只会引用,不会精细释放资源,导致程序一直会崩,十分苦恼。
因为,这些要“标记”释放的资源外层可能还有别的对象,所以一层层下来,很复杂,现在想要从根节点上,打断联系让它自动释放,是不是有这个可能?要怎么做才能更好更有序的管理这些非要手动控制的资源?
说实话,现在想换引擎的想法就有了,呵呵.

资源管理你只要把握addref和decRef成对就可以了,如果实在不行换一个引擎也不是不行 :rofl:

1赞