Lua GC - OK what am I doing wrong?

This topic is 4385 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi everyone, I'm using Lua in my game and I'm having some quite serious memory issues with it. Since i've just started out with Lua, there's not really that much going on. Only a few Lua functions are called every frame, but it seems that Lua just keeps allocating more and more memory over time. I'm not doing anything too complicated (only calling a few c-side functions in the per-frame lua function). I use: lua_gc(luaVM, LUA_GCCOUNT, 0); to get the current GC count. I've tried: lua_gc(luaVM, LUA_GCCOLLECT, 0); every frame but my frame rate takes a plunge after only a few minutes as the GC is spending more and more time doing it's thing. This is quite a serious issue for my game! To give you some idea of my issue: After 1000 frames: 600 fps 56 bytes used by lua After 50000 frames: 300 fps 2533 bytes used by lua This is the function that gets called every frame:
	-- called every frame
OnFrame = function()
-- get the renderer
local renderer = Renderer_GetCurrent()

-- clear the renderer (colour, zbuffer, stencil)
Renderer_Clear(renderer, true,true,false);

-- tell the renderer we're about to render stuff
Renderer_Begin(renderer)

-- render a grid (just for debugging)
Renderer_DebugDrawGrid(renderer, 0,0,0)

-- render the world (and therefore all the nodes)
World_Render(mainWorld)

-- tell the renderer we've finished rendering
Renderer_End(renderer)

-- present causes the renderer to copy itself to the screen
Renderer_Present(renderer)
end,


Thanks for any suggestions!

Share on other sites
Are you recreating the OnFrame function each time you update your frame? That could be the cause of the memory increase and the only explanation I could gather from your snippet. Could you post the entire script and how you are executing it?

Share on other sites
Sure, here's the code:

   // send a script message about this frame   ceScript->PushFunction("Messages", "OnFrame");   ceScript->CallFunction(0);

and the two functions:

void CScript::PushFunction(const char* tblName, const char* funcName){	// get function to be called	if (tblName)	{		lua_getglobal(luaVM, tblName);		// get function key 		lua_pushstring(luaVM, funcName);		// table resides at stack index -2 		lua_gettable(luaVM, -2);	}	else	{		// no table, just a global function		lua_getglobal(luaVM, funcName);		}	if (!lua_isfunction(luaVM, -1))	{		CONSOLE_ERR("Lua error : '%s' is not a function", funcName);		lua_pop(luaVM, 1);  // pop error message from the stack 		return;	}}BOOL CScript::CallFunction(int noofParams){	int			error;	// do the call 	error = lua_pcall(luaVM, noofParams, 1, 0);	if (error)	{		CONSOLE_ERR("Lua error : %s", lua_tostring(luaVM, -1));		lua_pop(luaVM, 1);  // pop error message from the stack 		return FALSE;	}	return TRUE;}

I should point out that the 'OnFrame' lua function is in the table 'Messages'. I took it out of that table (so it was global) but that made no difference.

Share on other sites
Also I get *no* memory leaks on program exit (via _CrtDumpMemoryLeaks()).

Share on other sites
I think the problem is with the CScript method PushFunction. Because it is not a lua_Function the stack is not getting cleaned up once you are done working. So garbage tends to stack up and the gc need more time to take care of it.

Try this and see if it helps:

void CScript::PushFunction(const char* tblName, const char* funcName){	// save the stack's starting state	const int top = lua_gettop(luaVM);	// get function to be called	if (tblName)	{		lua_getglobal(luaVM, tblName);		// get function key 		lua_pushstring(luaVM, funcName);		// table resides at stack index -2 		lua_gettable(luaVM, -2);		// remove the table that is still stacked		lua_remove(luaVM, -2);	}	else	{		// no table, just a global function		lua_getglobal(luaVM, funcName);		}	if (!lua_isfunction(luaVM, -1))	{		CONSOLE_ERR("Lua error : '%s' is not a function", funcName);		// restore the stack to its previous state.		lua_settop(luaVM, top);	}}

Share on other sites
OK I'll give that a go when I get home tonight and let you know how I get on.

Cheers.

Share on other sites
OK i've figured it out. I wrote a simple test that looks like:

	do	{		// get function key 		lua_pushstring(ceScript->GetLuaVM(), "DoNothing");		// call the function with 0 parameters and 0 returns		lua_pcall(ceScript->GetLuaVM(), 0, 0, 0);		// WARNING!!! Not calling this results in the stack not being clean		lua_pop(ceScript->GetLuaVM(), 1);				dprintf("gettop = %i\n", lua_gettop(ceScript->GetLuaVM()));		dprintf("Lua mem = %i\n", ceScript->GetMemoryUse());	}while(true);

Without the lua_pop(), the stack just keeps getting larger and larger. Which makes sense really, with every push you have to call pop (although lua_pcall() pops the arguments for you if there was any).

lua_gettop() is pretty damn usefull to see what's going on.

Anyway, thanks for the help.

Jim

1. 1
Rutin
29
2. 2
3. 3
4. 4
5. 5

• 13
• 13
• 11
• 10
• 13
• Forum Statistics

• Total Topics
632960
• Total Posts
3009473
• Who's Online (See full list)

There are no registered users currently online

×