lua-users home
lua-l archive

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


Am 22.05.2014 21:47 schröbte Coda Highland:
On Thu, May 22, 2014 at 12:36 PM, Eric Wing <ewmailing@gmail.com> wrote:
In this example:
- I create objectZ, objectA, and objectB (in that order).
- objectA keeps a strong reference to objectB and objectZ.
- I remove references to objectB and objectZ, proving objectA is
keeping them alive.
- I remove my reference to objectA and watch what garbage collection does.

I expect that objectA is "marked for finalization" first because it is
keeping objectB and objectZ alive.
Then objectB and objectZ may be "marked for finalization" (no order on
these is expected).
So "in the reverse order they were marked for finalization", I expect
the finalization order to be:
1) objectZ or objectB
2) objectB or objectZ
3) objectA

Your behavior is derived from expectations of a reference-counted
garbage collector. Lua doesn't refcount. It's mark-and-sweep -- as a
high-level overview, it maintains a list of all objects, and a list of
root objects (mostly the top-level _ENV and the registry). When it
does a sweep, it starts from the root objects and marks every object
that it can reach as accessible. Then it sweeps over the list of all
objects and flags every object that isn't marked as accessible for
finalization. Then it runs finalizers on the objects thus marked, in
reverse of the order that they were marked. On the next sweep, if the
object is marked as both "finalized" and "inaccessible" it's deleted.
(If it's marked as "finalized" but NOT marked as "inaccessible" it's
been resurrected. It'll never have the finalizer run again.)

I think there is still some confusion. The "mark" in "mark-and-sweep" or "mark as reachable" has nothing to do with "mark for finalization". The GC does the former when there are strong references to an object, while _you_ do the latter by setting a metatable with a non-nil `__gc` field for the first time. Setting the metatable usually (but not necessarily) conincides with object creation. So if you read "in reverse order they were marked for finalization", you can assume "in reverse order of creation" _unless_ you delay setting a metatable with a `__gc` field for some reason ...

And it seems that in Lua 5.3 the finalizer of a resurrected object will run again (we had a thread about this not long ago).


/s/ Adam


Philipp