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