关于 Luabinding 内存管理机制的修改意见征集

首先,我简单阐述一下现在 Luabinding 针对 C++ 对象的内存管理机制。

当在 Lua 里创建一个 C++ 对象时,这个 C++ 对象的指针会被包装为一个 Lua 值放入 Lua 虚拟机中。

  • 对于 Lua 来说,C++ 对象占用的内存就是一个指针的大小(通常只有几十字节);
  • C++ 对象实际占用的内存 Lua 虚拟机无法得知。

由于 cocos 的 C++ 对象都使用引用计数和自动释放机制,所以可能出现一个 C++ 对象正在被 Lua 使用时却已经自动删除的情况。要避免这个问题,最简单的做法:

  • 对于图像、动画等对象,都在用到的时候才创建;
  • 创建后立即加入场景,避免这些 C++ 对象被自动释放。

有些从 C++ 转过来的开发者,还是习惯使用 retain() 来保持 C++ 对象,然后再不需要的时候 release()。
而这种编码习惯其实是不符合 Lua 风格的。


目前有一种修改方式,就是让传入 Lua 虚拟机的 C++ 对象不再自动释放。
而是只有在 Lua 虚拟机做 GC(垃圾回收)的时候才会释放那些 C++ 对象。

但我个人认为这种机制会带来一些严重问题:

1. 很多 C++ 对象之间存在复杂的引用关系。只要其中一个 C++ 对象在 Lua 里使用过,那么所有和这个 C++ 对象存在依赖关系的对象都无法释放。只有等到 lua gc 时才能释放。
2. Lua VM 触发 gc 的时机是根据 lua vm 内存分配来决定的。lua vm 并不知道 C++ 对象占用了多少内存。所以可能出现某个 C++ 对象占用了不少内存,但 lua vm 迟迟不触发 gc 的问题。
3. 在网络化 app 里,第二个问题带来的影响是致命的。比如 http 请求每一次的请求都是一个新的 C++ 对象,而请求结果都会保存在 c++ 对象里。只要不做 lua gc,这些 c++ 对象就会堆积起来,占用大量内存。
4. gc 会导致明显的卡顿,开发者不可能在场景中频繁做 gc。所以游戏的内存占用会持续增加。

请大家各抒己见。

1赞

GC 会掉帧的。

再说我写了那么多 Lua 代码,从没用过 retain。。。

不太支持,这样的修改会使原本不太需要关注内存问题的lua变的复杂化,而且对原来的设计支持有的比较大的变动影响面太广,对应测试和应用来说不是很有利。

1赞

不太支持,可以 retain() 的部分 让lua的gc来回收吗? 这样就不需要release了

— Begin quote from ____

引用第6楼麒麟子于2014-08-06 14:29发表的 回 4楼(dualface) 的帖子 :
既然你可以通过技巧防止retain,那完全没有必要改这个东西。
直接附带一个编程指南即可。 http://www.cocoachina.com/bbs/job.php?action=topost&tid=219086&pid=1022865

— End quote

是的,我认为这是一个编码规范的问题。

为什么要修改呢?感觉没必要修改!!!

没改没什么问题, 这样一改绝对很多问题~暂时没能想到更好的决解方案~

从前有个故事叫“画蛇添足”,呵呵

为什么要修改呢?感觉没必要修改!!!

我也觉得没必要。应该避免用C++的代码规范来写lua,就像你应该不能用筷子吃西餐。。
呃,我也几乎没有手动retain过。。

不建议让 lua 的 gc 来管理 cpp 的释放,这样做的话,对于开发者用户就少了灵活性了。

如果要解决 cpp 对象过早释放的话,可以用一个编程最佳实践来解决。

不要改,千万不要……
:3:

没必要修改, 修改了还会让习惯了以前释放方式的, 重新去理解, 现在用着暂时没觉的有什么不好

大家意见还是比较统一嘛。

既然是编码规范问题,那就应该在wiki或者某些文档中作一个说明,以免没看过帖子的人碰到问题还到处捉虫。

目前还是支持原有的方案, lua现在的角色仅仅是动态化的C++, 开发习惯仍然要按C++的规矩来.
至于第二种方案, 什么时候以lua为主做引擎开发, 底层仅仅是OpenGL之类的接口, 才是真正的带gc引擎.

建议 quick 还是保持现状吧.

这东西没有找大家都公认的解决方案前, 维稳。

嗯,现在就是在搜集需求的阶段。
想听听大家的反馈。

我觉得没必要修改吧,这个是就当做quick的一种编码规范。

感觉没有必要,既然依赖cocos2dx的库,那么遵循retain、release得规范即可
毕竟cocos2dx里面的对象一般都会和比较大纹理内存关联,依赖GC来做这件事情,不靠谱。。。游戏里面卡顿什么的太可怕了。。。