[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Confused by Lua garbage collection tear down order when there are references between objects
- From: Eric Wing <ewmailing@...>
- Date: Thu, 22 May 2014 12:36:32 -0700
On 5/22/14, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
> This is a bug in the documentation: the correct should be "in the
> reverse order that they were marked for finalization".
I think I misunderstand "in the reverse order that they were marked
for finalization".
I am including a Lua-only example at the bottom to try to describe my confusion.
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
But in actuality, I see:
finalizing objectB
finalizing objectA
finalizing objectZ
This appears to be the "creation order", and I think what helped lead
to confusion about "creation order" vs. "marked for finalization
order".
> Many libraries expect this behavior and more often than not it does
> the expected thing.
In my (incorrect?) understanding of this, I agree with this. This is
exactly what I want and also what my library expects. But in my
(incorrect?) understanding, I'm not seeing this, but instead, I'm
seeing "creation order".
function my_gc(the_object)
print("finalizing ", the_object.name)
end
function CreateObject(obj_name)
local new_object = {}
new_object = { name=obj_name }
setmetatable(new_object, { __gc=my_gc})
print("Created object ", new_object.name)
return new_object
end
function AssociateReference(obj_a, obj_b)
if nil == obj_a.refownerlist then
obj_a.refownerlist = {}
end
obj_a.refownerlist[#obj_a.refownerlist+1] = obj_b
end
objectZ = CreateObject("objectZ")
objectA = CreateObject("objectA")
AssociateReference(objectA, objectZ)
objectZ = nil
collectgarbage()
print("objectZ = nil; collectgarbage()")
do
local objectB = CreateObject("objectB")
AssociateReference(objectA, objectB)
objectB = nil
collectgarbage()
end
collectgarbage()
print("objectB = nil; collectgarbage()")
objectA = nil
print("objectA = nil; collectgarbage()")
collectgarbage()
print("final collectgarbage() before quit")
Thanks,
Eric
--
Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/