1
votes

I have a C++ application which embeds Lua and periodically (~10 times per second) runs scripts that can create new userdata objects that allocate non-trivial amounts of memory (~1MiB each) on C++ side. The memory is correctly freed when these objects are garbage-collected, but the problem is that they don't seem to be collected until it's too late and the process starts consuming inordinate amounts of memory (many GiBs). I guess this happens because Lua GC thinks that these objects are just not worth collecting because they appear small on Lua side, and it has no idea how much memory do they actually consume. If this is correct, is there any way to tell it about the real cost of keeping these objects around?

For people familiar with C#, I'm basically looking for the equivalent of GC.AddMemoryPressure() for Lua.

2
If the userdata are being created with lua_newuserdata, then Lua knows about their size. If you're only wrapping userdata around C++ pointers pointing to memory allocated in C++, then Lua does not know and can't be told.lhf
Can you expand on what you mean by "too late"? What's the effect on the process and the system?Tom Blodget
"Too late" actually seems to mean "never", i.e. the main program runs out of RAM before they're collected.VZ.

2 Answers

0
votes

The closest thing you're going to get at present is LUA_GCSTEP. The manual says:

lua_gc

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

Controls the garbage collector. […] For more details about these options, see collectgarbage.


collectgarbage ([opt [, arg]])

This function is a generic interface to the garbage collector. It performs different functions according to its first argument, opt:

[…]

  • "step": performs a garbage-collection step. The step "size" is controlled by arg. With a zero value, the collector will perform one basic (indivisible) step. For non-zero values, the collector will perform as if that amount of memory (in KBytes) had been allocated by Lua. Returns true if the step finished a collection cycle.

(emphasis mine)

This will advance the GC once (as if that much was allocated), but that information isn't kept, meaning that parameters influencing the behavior for future collections (GC pause length, total memory in use, etc.) aren't affected. (So check if that's works well enough for you and if it doesn't maybe try playing with the GC pause and step multiplier.)

0
votes

No. there is no such mechanism in Lua.