lua-users home
lua-l archive

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


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/