[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Garbage collection question
- From: John Dunn <John_Dunn@...>
- Date: Mon, 9 Jul 2012 21:56:04 +0000
Our app allows users to register a Timer function which gets called periodically. I've noticed that some patterns of Lua code cause memory to grow to the point that the OS starts killing processes as if the garbage collector isn't being run. Other seemingly similar Lua code has flat memory usage.
The C code looks something like this ( simplified but basically the same )
static int functionIndex = -1;
static int SetHandler( lua_State* L ) {
if( functionIndex != - 1) {
luaL_unref(L, LUA_REGISTRYINDEX, functionIndex);
}
if( lua_isfunction(L,-1)) {
lua_pushvalue(L,-1);
functionIndex = luaL_ref(L,LUA_REGISTRYINDEX);
}
return 0;
}
static const struct luaL_reg TestLibMethods[] = {
{ "SetHandler", SetHandler },
{NULL, NULL}
};
static void CallHandler(lua_State* L) {
if(functionIndex != -1 ) {
lua_rawgeti(L, LUA_REGISTRYINDEX, functionIndex);
lua_pcall( L, 0, 0, 0 );
}
}
This code will run fine with no memory growth
function A_callback()
A()
End
function A()
Timer.SetHandler( A_callback )
end
Timer.Start( .1 )
A()
This code has unbounded memory growth
function A()
function A_callback()
A()
end
Timer.SetHandler( A_callback )
end
Timer.Start( .1 )
A()
This code ( basically above, but manually calling the gc ) has flat memory usage
function A()
function A_callback()
A()
end
Timer.SetHandler( A_callback )
collectgarbage("collect")
end
Timer.Start( .1 )
A()
So the only difference is that in once case the function assigned to SetHandler is contained within the function and in the other case it isn't. I could buy that somehow having the function be a child would cause an unexpected reference but then I don't understand why manually calling collectgarbage fixes anything. Any ideas what might be going on?