Ruby garbage disposal does not work as expected
In the following code:
class ExampleClass
def initialize
ObjectSpace.define_finalizer(self, proc{puts 'dead'})
end
end
ex = ExampleClass.new
ex = nil
GC.start
while true
# the while loop is to prevent the program from terminate
# if the program does terminate, the finalizer gets called in the end like expected
end
The finalizer is never called here and there is no exit. I was expecting the garbage collector to collect ex
as it was dereferenced. Why GC.start
doesn't it force you ex
to collect and summons finalizer to be called
right away?
source to share
I believe that when you create a new one Proc
( Proc
just calls Proc.new
, in Kernel
)
Creates a new Proc object bound to the current context.
means it retains a reference to the object self
and therefore can never be reversed for the garbage collector to collect it. You have to create Proc
inside a class method instead so that the context becomes the class and not the instance you are trying to destroy.
class ExampleClass
def initialize
ObjectSpace.define_finalizer(self, self.class.finalize)
end
def self.finalize
proc { puts "dead" }
end
end
ex = ExampleClass.new
# needed to do something with the object as well, not sure why,
# but it won't work without this line either
puts "object id = #{ex.object_id}"
ex = nil
GC.start
while true
end
and these outputs
object id = 70223915005060
dead
^Cexample.rb:20:in `<main>': Interrupt
source to share