K
Karsten Meier
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:
GC.enable
class RingNode
attr_accessor :next
attr_accessor rev
attr_reader :name
def initialize(aName)
@name = aName
ObjectSpace.define_finalizer(self,
self.class.methodfinalize).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
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")
a = nil
b = nil
c = nil
lonely = nil
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.
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:
GC.enable
class RingNode
attr_accessor :next
attr_accessor rev
attr_reader :name
def initialize(aName)
@name = aName
ObjectSpace.define_finalizer(self,
self.class.methodfinalize).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
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")
a = nil
b = nil
c = nil
lonely = nil
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.