Max,
I would put this text to a comment for clarity.
Feel free to ignore.
<snipped>The reason of two consequent <collectgarbage> calls is not for "mark and sweep" but rather for "full GC cycle + finalization of the resurrected objects". The first call implements full (even 1.5) GC cycle; as a result of this call some *objects* can be *released*, but the corresponding *memory* is preserved in another list (gc->mmudata, IIRC) to properly finalize the object (i.e. call __gc metamethod). Hence, the second call finally releases the memory for the objects resurrected within the sweep phase of the first call. Since Max allocates plain FFI objects with no <ffi.gc> finalizers, there is no need in the second <collectgarbage> call here.