From: Joel VanderWerf Date: 2004-08-24T06:43:53+09:00 Subject: Re: Circular References: How to prove that they are garbage collected 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. >