简体   繁体   中英

Lua garbage collection and C userdata

In my game engine I expose my Vector and Color objects to Lua, using userdata.

Now, for every even locally created Vector and Color from within Lua scripts, Luas memory usage goes up a bit, it doesn't fall until the garbage collector runs.

The garbage collector causes a small lagspike in my game.

Shouldn't the Vector and Color objects be immediately deleted if they are only used as arguments? For example like: myObject:SetPosition( Vector( 123,456 ) )

They aren't right now - the memory usage of Lua rises to 1,5 MB each second, then the lag spike occurs and it goes back to about 50KB.

  • How can I solve this problem, is it even solvable?

You can run a lua_setgcthreshold(L,0) to force an immediate garbage collection after you exit the function.

Edit: for 5.1 I'm seeing the following:

int lua_gc (lua_State *L, int what, int data);

Controls the garbage collector.

This function performs several tasks, according to the value of the parameter what:

    * LUA_GCSTOP: stops the garbage collector.
    * LUA_GCRESTART: restarts the garbage collector.
    * LUA_GCCOLLECT: performs a full garbage-collection cycle.
    * LUA_GCCOUNT: returns the current amount of memory (in Kbytes) in use by Lua.
    * LUA_GCCOUNTB: returns the remainder of dividing the current amount of bytes of memory in use by Lua by 1024.
    * LUA_GCSTEP: performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of data. The function returns 1 if the step finished a garbage-collection cycle.
    * LUA_GCSETPAUSE: sets data as the new value for the pause of the collector (see §2.10). The function returns the previous value of the pause.
    * LUA_GCSETSTEPMUL: sets data as the new value for the step multiplier of the collector (see §2.10). The function returns the previous value of the step multiplier.

In Lua, the only way an object like userdata can be deleted is by the garbage collector. You can call the garbage collector directly, like B Mitch wrote (use lua_gc(L, LUA_CGSTEP, ...) ), but there is no warranty that exactly your temporary object will be freed.

The best way to solve this is to avoid the creation of temporary objects. If you need to pass fixed parameters to methods like SetPosition , try to modify the API so that it also accepts numeric arguments, avoiding the creation of a temporary object, like so:

myObject:SetPosition(123, 456)

Lua Gems有一个关于Lua程序优化的好文章。

Remember, Lua doesn't know until runtime whether or not you saved those objects- you could have put them in a table in the registry, for example. You shouldn't even notice the impacts of collecting 1.5MB, there's another problem here.

Also, you're really being a waste making a new object for that. Remember that in Lua every object has to be dynamically allocated, so you're calling malloc to .. make a Vector object to hold two numbers? Write your function to take a pair of numeric arguments as an overload.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM