Neil Roberts
8/7/2008 3:28:00 PM
On Thu, Aug 07, 2008 at 11:10:32PM +0900, Larsenmtl Larsenmtl wrote:
> I'm having trouble understanding when Ruby GC kicks in for Object
> instances that are no longer referred to by anything. A simple code
> sample to illustrate:
Ruby uses a conservative garbage collector which means that an object
won't be destroyed unless there is no value in the stack or registered
global memory location which contains a value that looks like a
pointer to a Ruby object. So it's therefore not possible to reliably
know when Ruby will decide an object is no longer reachable.
For example, the Array#delete_at function returns the value deleted so
while evaluating that expression the interpreter may leave the
intermediate result on the stack temporarily so it won't get reaped.
You can increase the chances of your object losing all references by
evaluating the code with a deep recursive stack as in the example
below. I don't recommend actually doing this in practice though, it's
better to just trust that Ruby will *eventually* get rid of your
objects.
class TestClass
end
collection = []
def do_adds(collection, depth = 0)
return do_adds(collection, depth + 1) unless depth > 1000
collection << TestClass.new
collection << TestClass.new
collection << TestClass.new
collection << TestClass.new
nil
end
do_adds(collection)
def count_test_class(depth = 0)
return count_test_class(depth + 1) unless depth > 1000
numTC = 0
ObjectSpace.each_object{|obj| numTC += 1 if obj.class == TestClass }
puts numTC
end
count_test_class
def do_deletes(collection, depth = 0)
return do_deletes(collection, depth + 1) unless depth > 1000
collection.delete_at(0)
collection.delete_at(0)
collection.delete_at(0)
collection.delete_at(0)
nil
end
do_deletes(collection)
GC.start
count_test_class