你完全可以把很重的东西放在C++里,JS里跑业务逻辑 好像没有什么慢的情况出现。
我也是用COCOS2DX -JSB
主要是绑定代码的修改比较麻烦。
感谢回复,我已经花了两天的时间,手动把 Creator 1.6.2 的 v52 升级对应到了 cocos2dx 3.12 引擎了。
大部分的功能已经对应, mac,Android 的编译运行也都通过了,目前在手动处理 cocostudio 的绑定部分。
后续也许还有什么别的问题,再来咨询官方
你这叫升级?这是降级啊。。。
额?为什么这么说呢? 我是把 cocos2d-x 3.12 的 SpiderMonkey v33 升级到 v52 为什么说是降级呢?
我理解为,你手动把creator1.6里面的SpiderMonkey v52"升级"
到cocos2dx3.12里面的SpiderMonkey v33的版本。
今天继续测试 v52 的升级,期间碰到了几个问题,希望官方可以解惑一下。
- 关于
CC_ENABLE_GC_FOR_NATIVE_OBJECTS
在 cocos2d-x 3.1x 中,这个宏默认都是 0,注释也写的是:
By default this behavior is disabled by default
我下载了 Cocos Creator 1.6.2 beta.3,创建了一个 HelloWorld 工程,发现项目中的这个宏,默认是 1,也就是默认是启用的。
然后我试了下把这个宏关掉,再编译,发现会报错,原因是在这个宏不启用的情况下,ScriptingCore 中还残留这 SpiderMonkey v33 的一些函数的调用,如 JS::RemoveObjectRoot
, JS::AddNamedObjectRoot
。
是不是说,在新的 SpiderMonkey v52 环境下,官方已经强制用户使用 CC_ENABLE_GC_FOR_NATIVE_OBJECTS
这种模式了 ?
- jsb_RefFinalizeHook_finalize 崩溃问题 (这个最头痛)
这个可能是 cocostudio 绑定造成的问题 。
今天把我 cocostudio 部分的 auto manual 绑定给对应了一下,然后把之前游戏的 ui (json) 文件拿来做了下测试,结果在 jsb_RefFinalizeHook_finalize
的地方会发生崩溃,原因是:
int count = refObj->getReferenceCount();
这里的 count 已经是 0 了,导致,导致后面的 Ref::release 里面,断言失败
CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
对于这个问题,我做了些调查,现在能提供一些信息:
a. jsb_RefFinalizeHook_finalize
触发的时候,正常情况下,refObj
的类型是 cocos2d::Node*
, cocos2d::SpriteFrame*
等等。
但是出错的,refObj
的类型显示是:
b. 每次出现这个问题时候,都是因为解析一个 cocostudio ui 的 mainmenu.json 文件造成的,错误堆栈每次都一样 :
c. 在加载这个 mainmenu.json 界面之前,我已经成功加载和显示了一个 login.json 界面 (包含输入框,按钮之类的)。
d. 如果我修改一下 jsb_RefFinalizeHook_finalize
的代码,把 count == 0 的情况先放过:
int count = refObj->getReferenceCount();
if (count == 1)
{
refObj->autorelease();
}
else if (count == 0) {
// 放过
}
else
{
CC_SAFE_RELEASE(refObj);
}
这样的话,界面可以正常的加载显示,并且上面的按钮之类的也可以正常的使用。
P大下周一来解答你吧,帮你强力@panda一下。
感谢,我周末也会再多做一些调查尝试的。
是的
你遇到的 jsb_RefFinalizeHook_finalize 问题触发的时候已经有对象处在非正常状态了,JS 对象仍然存在的情况下其 C++ 引用计数为 0,这个调查没什么特别好的办法,需要在 preprocess macro 中设置 DEBUG_MODE 为 2,这样会打印更多的信息,可以在出错的时候检查 refObj 的指针,然后在历史 log 中搜索这个指针,看看之前是什么类型的对象,再继续研究为什么会发生问题
感谢回复。
上面提的问题已经解决,是一个 jsb_create_weak_jsobject
造成的问题。
经过上一周的测试,这次 v52 合并到 cocos2d-x 3.12 的尝试应该说是成功了,最大的优点就是安卓上的 jsb 计算能力得到了大幅的提升,已经更好的 GC 管理模式。
下次有时间的话,准备把 CocosCreator 1.7 的 JSB 2.0 给合并到 cocos2d-x 3.1x 里面,性能应该还会有更大的提升。
最近在使用中,发现了一个内存释放的问题,怎么都找不出原因,想要所以想要咨询一下官方 @panda
首先简单概括一下问题,在新的内存模型下,使用一张单独的图片创建 Sprite 后,无法回收释放图片。
下面是重现的步骤和一些说明(我的理解,可能有错的地方):
- 创建一个
cc.Sprite
this.sprite = new cc.Sprite("some.png");
这里先创建一个 Sprite 对象。
绑定层会 创建一个 native ref 对象,引用计数为1;并为其设置 jsb_RefFinalizeHook
在 GC 的时候会触发 jsb_RefFinalizeHook_finalize
- 添加到场景
this.addChild(this.sprite); // this == layer
这里的 this 是一个普通的 cc.Layer
。
这句话,native 会做两件事情
a. native 的 ref 引用计数 +1 ,目前为 2。
b. native 会反过来调用 js 中的 registerNativeRef
函数,把 sprite 和 layer 建立引用关系,防止被 GC
相当于 layer.__nativeRefs[0] <==> sprite
- 删除 Sprite (不在同一帧进行)
this.sprite.removeFromParent();
这里也会做两件事:
a. native 会调用 releaseScriptObject
,解除 layer.__nativeRefs[0] <==> sprite
的引用关系
b. 引用计数 -1,目前为 1,还不能析构
- 手动 GC ( (不在同一帧进行))
ScriptingCore::forceGC();
这里,应该会触发 sprite 的 jsb_RefFinalizeHook_finalize
,在这里,sprite
被 autorelease
-
下一个 mainloop,sprite 被析构
-
回收 texture
cc.director.purgeCachedData();
这里,removing unused texture some.png
会显示为被回收。
这个是我认为应该发生的正确流程,但是实际上,却不是这么顺利,这个步骤的 4 会发生问题: 无论手动 GC 多少次,sprite 的 jsb_RefFinalizeHook_finalize
也不会被调用。
除非我在第3步,removeFromParent
之后添加:
this.sprite = null;
那么在一下次的 GC 时,sprite jsb_RefFinalizeHook_finalize
才会触发。
这里我的疑问是,如果我有很多这种 引用对象的形式
,那是不是说我必须在想要删除回收资源之前,一个一个的将其设置为 null
?这个显然不太合理。
我也尝试了另一种做法:
- 不调用 removeFromParent,而是调用(模仿 Scene::cleanup 的做法)
ScriptingCore::releaseAllChildrenRecursive
这样做,在 GC 的时候,sprite jsb_RefFinalizeHook_finalize
也会触发,但是这时 sprite 的引用计数是2,还不会被autorelease。而再次调用 GC,sprite jsb_RefFinalizeHook_finalize
就再也不会触发了,因此 sprite 一直是保持计数1 的状态,无法析构。
希望官方解惑一下,是不是我的理解或是哪里的做法出了偏差,谢谢了
你描述的过程基本都是正确的,只是你不理解为什么不会触发 this.sprite 的回收。
这个其实很简单,既然 this.sprite 的引用还存在,就说明从 JS 层仍然可以访问到这个 JS 对象,那么它当然就不是垃圾,自然也不会被 GC 回收。
this.sprite = null; 之后,你之前创建的 JS 对象自然就访问不到了,因为没有任何索引了,那么 GC 就会把它当作垃圾回收掉,也就会触发 jsb_RefFinalizeHook_finalize 回调。
其实新内存模型的意义就在于此,只要 JS 对象不被回收,native 对象的引用计数就无法到达 0,无法被释放,这样保证了 JS 和 native 生命周期的一致性。
厉害 我眼馋creator很久了 无奈没本事自己把cocos2d-js升级过去.
这个内存释放很好理解, jsb中存在c++内存释放 与 js内存释放, 而CC_ENABLE_GC_FOR_NATIVE_OBJECTS就是将两者关联起来 js释放掉后才会释放c++对象. 也就是说你只需要保证js对象能够被内存回收就可以了, 而不是一定要 this.sprite = null;
js内存回收机制有两种, 引用计数与标记清除, 在你上面 =号 就是引用计数.
标记清除自己百度,总之就是你只需要要保证从js的global根对象无法访问到对象就可以了,例:
this.a = new Sprite();
this.a.b = new Sprite();
this.a = null;
这时候并不需要this.a.b =null
更多细节 暂不讨论
OVER
能顺便让libjs_static.a支持一下bitcode不
使用增量GC,尝试下这个
JS_SetGCParameter(_rt, JSGCParamKey::JSGC_MODE, JSGC_MODE_INCREMENTAL);
JS_SetGCParameter(_rt, JSGCParamKey::JSGC_SLICE_TIME_BUDGET, 50);
哥们,你移植jsb2.0到cocos2d-x 3.12上成功了吗?我现在也要考虑做这个事,前面终于啋过了cocos2d-x 3.13上的jsb的一些坑。
大佬 同遇到老版cocos2d-js spidermonkey计算远落后于lua,请问你的升级修改能做个教程吗,收费也可以
这个搞的有点年头了,可以加个 qq:453951749 ,然后细聊一下,看看你的需求