Re: Projects I may be willing to sponsor

  • From: Mike Pall <mike-1412@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 12 Dec 2014 12:15:35 +0100

Cosmin Apreutesei wrote:
> If the GC measures pressure in bytes (and not in number of objects or
> whatever), then the problem of keeping the pace with huge allocations
> is orthogonal to how those allocations are made -- so I was wondering
> if this problem wouldn't surface as well with Lua-only huge
> allocations coming from eg. file:read'*a', ffi.string() etc.

Well, yes, that's the same problem. Try reading a couple of 128 KB
files into a VM with only 1 MB. The GC will likely run out of
memory. Even if all of it might fit, if measured at every instant.

The problem is: a tracing GC (*) cannot measure at every instant,
because this is prohibitively expensive!

Every GC has various heuristics that measure memory pressure to
decide when to start collecting, decide how fast to collect (if
incremental) and when and how long to pause. Those heuristics
_will_ fail, if the allocation granularity is close to the memory
ceiling. The alternative would be to force a full GC at every
allocation or use an emergency GC (but that causes many more
complications).

Either way, it'll be expensive, performance-wise. Automatic memory
management is not the best solution in all cases. That's why
LuaJIT offers a mix of automatic and manual memory management.


(*) 'Tracing' in this context means it's tracing through the live
object graph, as opposed to a reference counting garbage
collector, which manages reference counts for each object. [The
terminology is not related to the concept of a trace compiler.]

Seen from another perspective, this is the key problem with a
reference counting GC: the basic algorithm effectively measures at
every instant (and has to act at every instant). That's why basic
RC is generally considered to be too expensive to be used for a
general-purpose GC (for real-world problems, not for toy VMs).

The more advanced RC schemes have to batch or delay deallocation
or do lazy handling of stack references to get acceptable
performance. But then you'll face the same issues as described
above.

There's a strong convergence between advanced tracing GCs and
advanced RC GCs on both performance and laziness. IMHO given that
RC has the cycle problem, it's better to invest in an advanced
tracing GC.

--Mike

Other related posts: