关于lua 垃圾收集不能全部收回内存的问题

lua拿不到内存的时候不会释放这个内存。稍微改写一下前天的调试函数:
void * MyLuaAlloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
if (nsize == 0)
{

}
else
{
if (memTotal - osize + nsize > 5 * 1024 * 1024)
return NULL;

}
}
将lua内存限制到5M,这样很快就能到达上限,此时基本上所有需要分配内存的脚本执行都会失败(c++端的lua_pcall()返回错误LUA_ERRMEM)。

在真机上测试,内存到达数百兆级别时,游戏不死但是没有反应,应该是lua写的逻辑已经处于瘫痪状态了。

  1. 尽量少用不能自动释放的C++类如CCPoint。实际上cocos2dx 3.0在lua中已经全部用lua的表来代替CCPoint等类,而且基本上不再导出不能自动释放的C++类
  2. 不需要经常去GC,但如果场景多资源多的情况下,作好场景资源的规划,在场景切换时作适当的清理是比较好的
    3.在手机上内存达到数百M时,肯定基本上都不行了,所以要将内存使用大小控制在合理的范围内。正常情况下做到这一点应该是没问题的,因为已经有这么多成功的案例在前,并没有听说是在lua自己的机制这方面受影响,反而通常要多考虑的是对使用资源时的优化和控制

楼上的意思是不是说这个问题没办法用治根的办法解决了?

我们的游戏设计是在大地图上发生很多故事,很可能只要玩家不去战斗,只是在地图上跑的话,就不会切地图。另外在地图表现上有创新,用C++内的数学计算模拟出伪3D的效果,所以需要大量的CCPoint传递。另外,我根据项目要求对引擎内部做了不少自己的扩展,所以不太可能在项目允许的时间内升级到3.0了。

我们的游戏资源使用没有任何问题,在每帧收集垃圾的情况下内存是稳定的(可以连续运行几天不长内存)。我说的上百兆的内存是指不收集垃圾的情况下CCPoint所积攒起来的内存,数倍于正常的内存使用量。

当前作为引擎的使用者,当然要千方百计规避各种未预料的问题。如果没有治本的办法,我打算监视lua内存量,到达一定数值就收集一次内存,防止无限上升。或者尝试一下将CCPoint也从CCObject继承下来( 顺便问一下,这样做的话需要在tolua中做什么样的改动? )。

作为多年的引擎开发者,站在引擎层这一级,我觉得用绕路的办法来解决问题是很不舒服的。我还是会抽点时间出来做一点自己的尝试,只是从来没系统研究过tolua和luajit的内部,并不指望能短期内能有什么成果。

忽然想到,是否有办法让CCPoint不从CCObject继承,但是也能走CCObject的lua内部管理方法的手段呢?

按目前的结果确实不知道怎么来解决,毕竟现在不可能去动lua的底层。除非是我测试和分析的结果有误,另有原因,但我现在没有发现有这方面的问题。
将CCPoint也从CCObject继承下来还是比较简单的,在类的定义那里继承就不用说了;然后就是去修改定义了CCPoint的tolua文件,改完用脚本重新自动生成绑定文件就可以了。对tolua自动生成的文件稍为熟悉一点的话,还可以自己改一下CCPoint的create函数的绑定代码,两三行就差不多了。楼主可以先试一下,有问题可以跟我讨论。

内存的问题总是让人头痛

mark mark

mark
之前也遇到这个问题

话说这个问题彻底解决了?究其根源到底在哪了呢?分享一下,大家都学习学习!

我算是挖坟么- -但是目前;我做的游戏也出现你这样的问题了;大场景;长时间很难切换;而且精灵数量又大;内存也是只涨不降= =gc虽然也有用到了……
o(︶︿︶)o 也不知道楼主最后怎么解决的;求一个好的方法。
CCPoint尽量不用。。。

这个问题现在已经找到原因并完全解决。开始考虑过自动清理的机制,但这需要监控所记录的C++对象数的变化,效率影响较大。现在的解决方案是提供一个tolua.fullgc()接口,在适当的时候调用一下即可。

可以到https://github.com/chukong/quick-cocos2d-x的master分支最新版本下,取lib/cocos2d-x/scripting/lua/tolua目录下的所有文件来更新现有版本,同时在framework目录下增加的一个toluaEx.lua文件也放到现有版本中。

使用时,先require "framework.toluaEx"之后,就可以调用tolua.fullgc()了。

这真是个好消息。谢谢诸位的成果。

不过我的项目已经用不上啦,当时因为没有正规解法,只好下定决心,把所有直接传递c++对象到lua的接口函数全部重新写了一遍,比如原先返回CCPoint对象,改成返回lua table {x,y}。花了大概两周时间。

quick 3.5上 调用 tolua.fullgc() 直接报错了,:69: attempt to call field ‘getregval’ (a nil value)
是什么情况呢?