Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby上规范的强制GC_Ruby_Rspec_Garbage Collection_Specifications - Fatal编程技术网

Ruby上规范的强制GC

Ruby上规范的强制GC,ruby,rspec,garbage-collection,specifications,Ruby,Rspec,Garbage Collection,Specifications,我在一个项目中工作,那时我将管理许多由外部C dll创建的对象。 现在,我从我的类范围开始,它实现了一种模式,用于保留其他“可释放”对象的内存。因此,当范围对象被销毁时,我需要为范围对象将维护的每个引用调用一个release方法。 这是我的代码: module ServiceBus class Scope def initialize @releaseables = [] ObjectSpace.define_finalizer(self, self.cl

我在一个项目中工作,那时我将管理许多由外部C dll创建的对象。 现在,我从我的类范围开始,它实现了一种模式,用于保留其他“可释放”对象的内存。因此,当范围对象被销毁时,我需要为范围对象将维护的每个引用调用一个release方法。 这是我的代码:

module ServiceBus

  class Scope
    def initialize
      @releaseables = []

      ObjectSpace.define_finalizer(self, self.class.finalize(@releaseables))
    end

    def self.finalize(releaseables)
      proc { releaseables.each { |obj| obj.release } }
    end

    def add_obj(obj)
      raise "#{self.class} only support releasbles objects" unless obj.respond_to?(:release)
      @releaseables << obj
    end
  end
end
这是失败的,因为finalize永远不会在预期之前执行。 我应该如何强制GC销毁我的主题对象。


提前感谢

据我所知,这是不可能的。由特定的Ruby实现决定对象是否以及何时被实际销毁。由于垃圾收集是特定于实现的,因此不作任何保证。不幸的是,这意味着可能永远不会调用终结器。然而,我认为规范也可以单独测试终结器。换句话说,当您手动触发GC时,您还可以手动触发终结器并测试其效果

subject(:subject) { ServiceBus::Scope.new }

context "obj respons_to release" do
  let(:obj) do
    obj = double("ReleaseableObject")
    allow(obj).to receive(:release)

    obj
  end

  it "success" do
    subject.add_obj obj
  end

  it "call invoke for all added objects" do
    other_obj = double("ReleaseableObject")
    allow(other_obj).to receive(:release)

    subject.add_obj obj
    subject.add_obj other_obj

    subject = nil
    GC.start

    expect(other_obj).to have_received(:release)
    expect(other_obj).to have_received(:release)
  end
end