当您认为应该在您提供的代码中完成时,不会发生最终确定。
例如,如果您将这一行更改为:
ObjectSpace.define_finalizer(self, proc do; puts "self is type #{self.class.name} and equals #{self.inspect}"; self.delete; end)
然后注意它是如何什么都不做的(即使我坐在那里等了一会儿),直到我杀死 irb:
... (entered class definition from above with that define_finalizer)
1.9.3-p392 :021 > Foo.no_foo # => 0
=> 0
1.9.3-p392 :022 > f = Foo.new
creating object
=> #<Foo:0x007fb5730f3e00>
1.9.3-p392 :023 > f = nil
=> nil
1.9.3-p392 :024 >
1.9.3-p392 :025 > GC.start
=> nil
1.9.3-p392 :026 > Foo.no_foo # => 1
=> 1
1.9.3-p392 :027 > ^D
self is type Foo and equals #<Foo:0x007fb5730f3e00>
deleting object
所以第一个假设可能是没有调用GC。但是,让我们看看它使用GC::Profiler
:
1.9.3p392 :001 > GC::Profiler.enable
... (entered class definition from above)
1.9.3p392 :022 > puts GC::Profiler.result
GC 17 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
=> nil
1.9.3p392 :023 > Foo.no_foo # => 0
=> 0
1.9.3p392 :024 > f = Foo.new
creating object
=> #<Foo:0x007fe2fc806808>
1.9.3p392 :025 > puts GC::Profiler.result
GC 17 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
=> nil
1.9.3p392 :026 > f = nil
=> nil
1.9.3p392 :027 > puts GC::Profiler.result
GC 17 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
=> nil
1.9.3p392 :028 > GC.start
=> nil
1.9.3p392 :029 > puts GC::Profiler.result
GC 18 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
1 0.161 997280 2257680 56442 3.96199999999999352696
=> nil
1.9.3p392 :030 > Foo.no_foo # => 1
=> 1
1.9.3p392 :031 > ^D
deleting object
因此,当您要求 GC 时,它看起来正在被调用,但直到 irb 退出它才最终确定 Foo 实例。