我做了个小实验:
在C++中写了一个lua内存分配函数,并开了一个容器记录所有lua内存申请和删除的记录:
std::map<void*, int> g_luaMemRecord;
void * MyLuaAlloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
if (nsize == 0)
{
free(ptr);
if (g_bLog)
{
g_luaMemRecord.erase(ptr);
}
return NULL;
}
else
{
void *p = realloc(ptr, nsize);
if (g_bLog)
{
g_luaMemRecord.erase(ptr);
g_luaMemRecord = nsize;
}
return p;
}
}
在 CCLuaStack::init(void) 中,将
m_state = lua_open();
改成
m_state = lua_newstate(MyLuaAlloc, NULL);
这样就接管了lua内存分配。
然后启动游戏,等游戏初始化完成后,先在调试器中将g_bLog设为true,开始记录内存操作。
执行下面的lua程序:
bigTable = {}
for i=1, 50000 do
table.insert(bigTable, CCPoint(i,i))
end
bigTable = nil
collectgarbage(“collect”)
然后在调试器中观察g_luaMemRecord,可以发现里边有2项大小为1572864的内存块。
如果不是创建CCPoint对象,而是改成
table.insert(bigTable, {1,2,3,i} )
则观察到g_luaMemRecord空空如也。
我猜想这个问题可能是tolua引入的,也可能是luajit内部的某种"只增不减"的机制,比如用vector来管理所有lightuserdata。
to开发组:期待你们的回复,即使回复说暂时不处理,也比杳无音讯要好!