有没有办法强制所有Ruby(MRI)终结器同步运行?

时间:2015-10-03 15:02:56

标签: ruby garbage-collection

我正在尝试对终结器代码进行单元测试,但是按顺序 为此,我需要知道 运行的所有终结器。 这样,我可以判断终结器应该具有的效果 实现了,实际上是实现了。

到目前为止,我没有运气(在MRI 2.2上),终结者似乎总是如此 运行“以后”

要清楚,我没有兴趣强制GC和终结器运行 除了单元测试之外的任何其他地方,但最终确定逻辑是 细致入微,所以我真的不舒服,让它没有经过考验。

V8提供了一种仅用于此目的的方法,它非常方便, https://github.com/v8/v8/blob/master/include/v8.h#L5667但我没有 能够在Ruby中找到同样可靠的东西。

所以我的问题是,如何强制完成所有的同步运行 GC和所有终结器?即使这样做,也可以通过C扩展来完成 没有公共API可以用吗?

以下是演示问题的脚本链接

https://gist.github.com/cowboyd/6caf13104a26210ec525

1 个答案:

答案 0 :(得分:2)

谷歌搜索,有人在2003年问了同样的问题(!),马茨自己回答说基本没有:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/87753

In message "How to unit test finalizers?"
    on 03/12/11, Samuel Tesla <samuel / thoughtlocker.net> writes:

|> Nothing.  There's no way to "ensure" instance to be GC'ed except for
|> program termination.  That's a weak (or charm) point of Ruby's GC.
|
|That's fine.  I'm guessing that the GC will eventually, most likely,
|collect those references.  The question then becomes, how can I
|reliably unit test my finalizer code if I can't reliably get it to
|execute?

How about not relying on finalizers, i.e. separate finalizing process
into a method, then call the method explicitly in the test?  You don't
have to test whether finalizers are called.  That's my responsibility.

              matz.