Why isn't my Ruby object deleted when the last reference goes out of scope?
I've found a weird effect when trying to track down a memory leak in a Rails app. Can anyone explain what's going on here?
Save this script as a plain Ruby script (Rails not necessary):
class Fnord
def to_s
'fnord'
end
end
def test
f = Fnord.new
end
test
GC.start
sleep 2
ObjectSpace.each_object do |o|
puts o if o.is_a? Fnord
end
When I run this via
ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]
I get the following:
bash $ ruby var_test
fnord
Although the variable f is out of scope, there are no other references to the single Fnord object, and I've garbage collected, the object still seems to exist. Is this a nefarious memory l开发者_如何学JAVAeak of some sort, or am I completely missing something about Ruby?
Further, if I change the test method to this:
def test
f = Fnord.new
f = nil
end
I get no output. But surely this should not change the semantics here?
Many thanks!
I think the difference between your two versions is not about the value of f, but about the fact that in your first version test
will return the new Fnord object while in the second version test
will return nil
.
As a matter of fact the object will be garbage collected if any value comes between Fnord.new
and GC.start
. For example simply adding a line 42
between the call to test
and the call to GC.start
will cause the object to be collected.
I'm not sure why this is the case, but I suspect that the ruby interpreter holds on to the value of the last evaluated expression for some reason.
精彩评论