我在一个项目中工作,我将管理由外部 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 销毁我的主题对象。
提前致谢!!!
最佳答案
据我所知,这是不可能的。由特定的 Ruby 实现来决定是否以及何时实际销毁对象。由于垃圾收集是特定于实现的,因此不做任何保证。不幸的是,这意味着终结器可能永远不会被调用。但是,我认为规范也可以单独测试终结器。换句话说,当你手动触发GC时,你还不如手动触发finalizer并测试它的效果。
关于ruby - 针对 Ruby 规范强制 GC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25334509/