views:

213

answers:

3

Hi,

In ruby all classes are objects of class Class. Since classes are also objects, does a Ruby VM follow the same Garbage Collection strategy for class objects? What determines that a class object is safe for garbage collection?

Thanks

A: 

When there is nothing linking to the object, then it's safe to get rid of it. As far as -when- garbage collection is run, that is beyond my knowledge.

Trevoke
This is true in general, but classes can be seen as a special case. For example if a class has no instances and is not subclassed by any other class it has no 'links' (as you say) but is it really safe to GC? What if someone intends to build an instance from it at a later date. I do not think the situation is as clear-cut for classes as you make out :)
banister
@banister: This is exactly the case I wanted to point out amongst other special cases where a GC might have to treat a class object in a special way
Vaibhav Gumashta
Fair enough.A class is nothing but a constant, isn't it?And you can't get rid of a constant, since it's a variable within an environment (even if it's the 'main' object of IRB, or the runtime), until the environment is done."class String" is the same thing as "String = Class.new".
Trevoke
@Trevoke: Oops! A class is not a constant; it's the "class name" that is a constant
Vaibhav Gumashta
@Vaibhav at least you understood what I meant :-)
Trevoke
@banister: As long as there is a constant pointing to the class, there most certainly is a link. However you can remove constants via remove_const, and you can create classes that are never referenced by a constant, i.e. that have no name. So if that is the case and if there are no subclasses or instances and also no variables or constants pointing to a class, then there are no links. In that case it's not possible to access or instantiate the class in any way without using ObjectSpace (which would also work with objects eligible for GC)).
sepp2k
@sepp2k, good point. So are you saying that classes (and even the special classes you're talking about with absolutely no 'links') are not GC'd ?
banister
@banister: If I knew, I'd have posted an answer. ;-) All I'm saying is they could be GCed in theory.
sepp2k
@banister, @sepp2k : Well, I just tried to create a class in a method, and Ruby's compiler does _not_ like that. Not at all. http://gist.github.com/304870 If I understand correctly, the first class won't get GC'd because it has a name, the second one will disappear when the method ends, and the third one will probably be GC'd when the GC runs. I am not a Ruby guru so I could be wrong, but that's what I think will happen.
Trevoke
A: 

I have no idea what the answer is, but could you not find out by experimentation? Have a look at the pickaxe. I'm sure that this is a very naive test, and someone can do better, but you get the idea:

puts "program start"    
include ObjectSpace

class SfbdTest
   def initialize(a)
      @a = a
   end
end
define_finalizer(SfbdTest, proc{|id| puts "GC on class"} )

puts "creating instance"
x = SfbdTest.new(1)
define_finalizer(x, proc{|id| puts "GC on instance"} )

puts "zombie-ing instance"
x = nil

puts "forcing GC"
GC.start()

puts "program end"

Produces:

sfbd@thing:~$ ruby -w test.rb
program start
creating instance
zombie-ing instance
forcing GC
program end
GC on instance
GC on class
sfbd@thing:~$ 

Looks like it needs a thread, but unfortunately I'm supposed to be working, sorry...

Shadowfirebird
+1  A: 

I tested this out, the answer is it looks like it does.

irb(main):001:0> x = [] #Memory Usage = 12MB
=> []
irb(main):002:0> 120000.times {x << Class.new} #Memory usage now at 41 MB
=> 120000
irb(main):013:0> x = []
=> []
irb(main):011:0> GC.start() #Memory usage now at 13MB
=> nil
Andrew Cholakian