Array Of Objects, Removing Element From Memory

  • Thread starter Larsenmtl Larsenmtl
  • Start date
L

Larsenmtl Larsenmtl

Ruby Fans,

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:

Code:
class TestClass
end

collection = []
collection << TestClass.new
collection << TestClass.new
collection << TestClass.new
collection << TestClass.new

numTC = 0
ObjectSpace.each_object{|obj| numTC += 1 if obj.class == TestClass }
puts numTC

collection.delete_at(0)
collection.delete_at(0)
collection.delete_at(0)
collection.delete_at(0)

numTC = 0
ObjectSpace.each_object{|obj| numTC += 1 if obj.class == TestClass }
puts numTC

If you run this you'll see that 4 TestClass instances are still in the
ObjectSpace even after they are deleted from the collection array. I
tried manually calling the garbage collector after deleting the elements
from the array but I get the same result.

How do I get Ruby to trash those instances?

Thanks,
Mark
 
N

Neil Roberts

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
 
G

Gregory Brown

If you run this you'll see that 4 TestClass instances are still in the
ObjectSpace even after they are deleted from the collection array. I
tried manually calling the garbage collector after deleting the elements
from the array but I get the same result.

How do I get Ruby to trash those instances?

There is a long thread on this issue from just last week:
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/cdf5cecac633cefa/f6ba4d82079e97bc

Though I must admit it worries a bit for me to see people using
ObjectSpace to check memory consumption. To me, this either means
that folks are getting concerned about issues that they don't need to
worry about, or that there are larger problems in their code with
respect to memory consumption. I don't mean you here, just in
general.

-greg
 
L

Larsenmtl Larsenmtl

Thanks for the replys. Both of you confirmed that my methods are sound,
I'm just not understanding the conservative nature of the GC.
that there are larger problems in their code with
respect to memory consumption. I don't mean you here, just in
general.

It turns out it is my code. In my actual application I'm not using
Array.delete_at but Array.shift. This seems to be my problem:

http://www.ruby-forum.com/topic/94458

I should have searched better.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top