我正在玩红宝石终结器,并注意到一些对我来说非常奇怪的行为。我可以将触发代码减少到以下内容:
require "weakref"
class Foo
def initialize
ObjectSpace.define_finalizer(self, self.class.finalize)
end
def self.finalize
proc {
puts "finalizing"
}
end
end
Foo.new # does not work
#WeakRef.new(foo) # Using this instead, everything works as expected
sleep 1
ObjectSpace.garbage_collect
puts "... this did not finalize the object"
Foo.new
ObjectSpace.garbage_collect
puts "but this did?"
正如程序所说,在第二次调用 Foo.new 之前没有运行终结器。我尝试在第一次调用垃圾收集器之前增加更多延迟(尽管据我所知,它根本不需要),但这无济于事。
奇怪的是,如果我使用注释掉的行 i,第一个终结器会按照我的预期被调用。在程序退出之前,第二个仍然没有被调用。
谁能解释为什么会这样?我正在运行带有 ruby 1.9.3p194(2012-04-20 修订版 35410)[x86_64-linux] 的 Ubuntu 12.10。我尝试阅读弱引用代码,但据我所知,它所做的只是存储对象 object_id 以便以后检索它。
编辑:我知道在这种情况下手动调用垃圾收集器是没有意义的。我只是想了解这背后的机制。