From: Karsten Meier Date: 2004-08-24T07:10:43+09:00 Subject: Re: Circular References: How to prove that they are garbage collected Thanks, this is doing the trick. Even when I put the assignments to nil also in the function (just to be sure that there is has nothing to do with C++ style destruction of objects on the stack when leaving the function) Joel VanderWerf wrote: > Karsten Meier wrote: > >> Hello Ruby Fans >> >> I'm converting a perl example which deals with the circular data >> structures, and how to make sure they are destroyed properly. >> (For the pleac cookbook, pleac.sourceforge.net) >> >> I have read several times that the garbage collector has no problems >> with circular references, so I tried to prove it. >> But with my ruby 1.8.0 it looks like the garbage collector >> does not destroys the Node A, B and C, but only the lonely node: > > > "Only the lonely > Node the way I feel tonight" > > ... hehe. Sorry Roy Orbison. > > Anyway, try it with the following 3 additional lines. All four nodes > print their message before the "Garbage colection called" message. I > think what's going on is conservatism. Keeping the local vars in a > method makes sure that stack frame is gone begore the GC starts. > >> GC.enable >> >> class RingNode >> attr_accessor :next >> attr_accessor :prev >> attr_reader :name >> >> def initialize(aName) >> @name = aName >> ObjectSpace.define_finalizer(self, >> self.class.method(:finalize).to_proc) >> end >> >> def RingNode.finalize(id) >> puts "Node #{id} dying" >> end >> >> def RingNode.show_all_objects >> ObjectSpace.each_object {|id| >> puts id.name if id.class == RingNode >> } >> end >> end >> > def main > >> a = RingNode.new("Node A") >> b = RingNode.new("Node B") >> c = RingNode.new("Node C") >> a.next = b >> b.next = c >> c.next = a >> a.prev = c >> c.prev = b >> b.prev = a >> lonely = RingNode.new("Lonely node") > > end > >> >> a = nil >> b = nil >> c = nil >> lonely = nil >> > main > >> GC.start >> puts "Garbage Collection called" >> RingNode.show_all_objects >> puts "End of Program" >> >> >> What happens is that Noda A,B,C get destroyed, but after the end of >> the program. If I comment out the finalizer (in case I made an error >> with it) and only use the ObjectSpace.each_object, I see also Node >> A,B,C after the garbage collection. >> > > >