lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Finally I have found a (hopfully) good solution for my GC and finalizers issue: 
It consists in speeding up the GC cycle transparently for the user by running GC steps in the background when the host application is idle, as long as an active (i.e. not paused) GC cycle is on-going.

The important thing here is the need for synchronization with Lua's incremental GC cycle.

It comes from the combination of several (contradictory) requirements related to the class of applications we have here: running user interactions written in Lua on a mobile battery-powered device.

These requirements are:
- do not drain the battery by running random GC cycles when not needed,
- do not cause visible lags in the application by executing too long GC steps in the course of the program,
- ensure that a GC cycle, once started, will complete in a short period of time, so that external memory and system resources retained by the Lua program can be released when not used anymore,
- in possible circumstances where the Lua program uses 100% of the available CPU, let Lua incremental GC do the job (even if this slows down slightly the user experience, it is of high importance that the memory usage does not grow out of control).

For this list of requirements, none of the usual ways of doing found in the Lua literature or posts is appropriate: running full GC cycles regularly in stop-the-world mode is good for memory but unacceptable from a user interaction perspective, letting the Lua GC run on the fly in incremental mode is better but will still cause very annoying lags at certain moments, and stopping the GC and running GC steps periodically may have a very bad impact on the device battery.

So the solution is simple: run as many GC steps as possible in the background when the CPU is idle, but do this only when necessary, i.e. in a synchronized way with the Lua internal GC states. Namely the background GC steps shall be done when the GC is not paused.

This synchronization is not possible with Lua current APIs, so I've added a new function in lua.h for this: lua_gcsethandler;

	typedef void (*lua_GCStateHandler) (lua_State *L, int isgcpaused);

	LUA_API void (lua_gcsethandler) (lua_State *L, lua_GCStateHandler handler);

The handler function is called whenever the GC enters or leaves the "paused" state.

To make this code available (as well as other minor additions I made to Lua), I have created a public repository here: https://bitbucket.org/jean_luc/lua-5.2-jl-patches

All comments / opinions about this are welcome.

Jean-Luc