ruby – 在创建第二个对象之前未调用Finalizer,除非使用weakref
发布时间:2020-12-17 02:33:22 所属栏目:百科 来源:网络整理
导读:我正在玩 ruby终结器,并注意到一些对我来说很奇怪的行为.我可以将触发代码减少到以下内容: require "weakref"class Foo def initialize ObjectSpace.define_finalizer(self,self.class.finalize) end def self.finalize proc { puts "finalizing" } endendF
我正在玩
ruby终结器,并注意到一些对我来说很奇怪的行为.我可以将触发代码减少到以下内容:
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.我尝试读取weakref代码,但据我所知,它所做的只是存储对象object_id以便以后检索它. 编辑: 解决方法
您无法收集您的Foo参考,因为它在您的终结器中被引用!因此,因为终结器本身持有对象的引用,所以GC从不收集它,因此从不触发终结器.您只需使用WeakRef作为终结器本身就可以解决这个问题:
require "weakref" class Foo class << self attr_accessor :objects_finalized def finalize proc { @objects_finalized ||= 0 @objects_finalized += 1 } end end def initialize ObjectSpace.define_finalizer WeakRef.new(self),self.class.finalize end end describe Foo do it "should be collected" do Foo.new expect { GC.start }.to change { ObjectSpace.each_object(Foo){} }.from(1).to(0) end it "should be finalized when it is collected" do expect { begin; Foo.new; end; GC.start }.to change { Foo.objects_finalized }.from(nil).to(1) end end 结果如下: % rspec weakref.rb .. Finished in 0.03322 seconds 2 examples,0 failures (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |