当我管理由外部C dll创建的很多对象时,我正在一个项目中工作。 现在,我从我的类Scope开始,它实现了一个模式来保存其他“可释放”对象的内存。因此,当Scope对象被销毁时,我需要为Scope对象将维护的每个引用调用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
和我的规格:
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
这是失败的,因为finalize永远不会在期望之前执行。 我应该如何强制GC销毁我的主题对象。
提前致谢!!!
答案 0 :(得分:0)
据我所知,这是不可能的。由特定的Ruby实现决定是否以及何时实际销毁对象。由于垃圾收集是特定于实现的,因此不做任何保证。遗憾的是,这可能永远不会被称为终结者。但是,我认为规范也可以单独测试终结器。换句话说,当您手动触发GC时,您也可以手动触发终结器并测试其效果。