ruby – 在创建第二个对象之前未调用Finalizer,除非使用weakref

ruby – 在创建第二个对象之前未调用Finalizer,除非使用weakref,第1张

概述我正在玩 ruby终结器,并注意到一些对我来说很奇怪的行为.我可以将触发代码减少到以下内容: require "weakref"class Foo def initialize ObjectSpace.define_finalizer(self, self.class.finalize) end def self.finalize pr 我正在玩 ruby终结器,并注意到一些对我来说很奇怪的行为.我可以将触发代码减少到以下内容:

require "weakref"class Foo    def initialize        ObjectSpace.define_finalizer(self,self.class.finalize)    end    def self.finalize        proc {            puts "finalizing"        }    endendFoo.new # does not work#WeakRef.new(foo) # Using this instead,everything works as expectedsleep 1ObjectSpace.garbage_collectputs "... this dID not finalize the object"Foo.newObjectSpace.garbage_collectputs "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  endenddescribe 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)  endend

结果如下:

% rspec weakref.rb..Finished in 0.03322 seconds2 examples,0 failures
总结

以上是内存溢出为你收集整理的ruby – 在创建第二个对象之前未调用Finalizer,除非使用weakref全部内容,希望文章能够帮你解决ruby – 在创建第二个对象之前未调用Finalizer,除非使用weakref所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1279538.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存