物理引擎chipmunk性能问题

###环境
cocos2dx-3.17 JSB
###现象
界面上平常有50个元素,多的时候100~200。
使用物理引擎chipmunk做碰撞检测。
Android(OPPO A83)表现很差,从最开始能保持50~60帧,10多分钟后下降到10帧。
iOS(iPhone 6)好一点,能至少坚持半小时。
在停止碰撞后,帧率回升,再开始碰撞,帧率持续下降。
通过 Date.now() 打印时间,this.space.step(dt) 耗时很长。
尝试改变迭代次数 setIterations 设置为1,还是没有改善。
###猜测
感觉是有什么东西没有释放掉。
在框架中也有看到JSB_cpBody_finalizeJSB_cpShape_finalize 绑定。
但是去调用body.finalize()shape.finalize() 却找不到该方法,能用的只有destroy
本人初次使用物理引擎,还请各位大神解疑。
最后附上回收代码。

recycle: function (sp) {
    var self = this;
    var func = function () {
        if (cc.sys.isObjectValid(sp)) {
            var body = sp.getBody();
            var shape = body.shape;

            sp.stopAllActions();
            sp.setVisible(false);

            self.space.removeShape(shape);
            shape.destroy();

            self.space.removeBody(body);
            body.destroy();

            sp.removeAllChildren();
            sp.removeFromParent();
        } else {
            cc.log("recycle duplicate!");
        }
    };
    if (this.space.isLocked()) {
        this.space.addPostStepCallback(func);
    } else {
        func();
    }
},

自己的问题还是自己解决吧。

通过最小化代码,发现是 addPostStepCallback 的原因。

查看源码,有个 free(data) 注释掉了,但是打开它会报错。

应该是有内存泄漏,还需要引擎开发组小伙伴确认。

bool JSB_cpSpace_addPostStepCallback(JSContext *cx, uint32_t argc, jsval *vp)
{
    JSB_PRECONDITION2(argc == 1, cx, false, "Invalid number of arguments");

    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    JSObject* jsthis = args.thisv().toObjectOrNull();
    jsb_c_proxy_s* proxy = jsb_get_c_proxy_for_jsobject(jsthis);
    cpSpace* space = (cpSpace*)proxy->handle;

    __PostStep_data* volatile data = (__PostStep_data*)malloc(sizeof(__PostStep_data));
    if (!data)
        return false;

    data->cx = cx;
    data->func = args.get(0);
    js_add_object_reference(args.thisv(), args.get(0));

    cpSpaceAddPostStepCallback(space, (cpPostStepFunc)__JSB_PostStep_callback, data, data);

        //free(data);
    args.rval().setUndefined();
    return true;
}

分享下目前我的处理。

缓存了一个回收队列,
需要回收的时候就入队,
统一在 this.space.step(dt) 方法后回收掉。

update: function (dt) {
    this.space.step(dt);
    this.recycleObject();
},

跑了一晚上没有卡死,已经满足需求了。:wink: