Ruby Symbol#to_proc泄漏1.9.2-p180中的引用? [英] Ruby Symbol#to_proc leaks references in 1.9.2-p180?
问题描述
好的,这是我第二次尝试调试我的Sinatra应用程序的内存问题.我相信这次我已将其固定在简单的示例代码中.
Ok, this is my second attempt at debugging the memory issues with my Sinatra app. I believe I have it nailed down into simple sample code this time.
似乎当我通过.map(&:some_method)
过滤数组时,它会导致该数组中的项目无法得到垃圾回收.运行等效的.map{|x| x.some_method}
完全可以.
It seems when I filter an array through .map(&:some_method)
, it causes the items in that array to not get garbage collected. Running the equivalent .map{|x| x.some_method}
is totally fine.
演示:给出一个简单的示例类:
Demonstration: Given a simple sample class:
class C
def foo
"foo"
end
end
如果我在IRB中运行以下命令,它将被正常收集:
If I run the following in IRB, it gets collected normally:
ruby-1.9.2-p180 :001 > a = 10.times.map{C.new}
=> [...]
ruby-1.9.2-p180 :002 > b = a.map{|x| x.foo}
=> ["foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo"]
ruby-1.9.2-p180 :003 > ObjectSpace.each_object(C){}
=> 10
ruby-1.9.2-p180 :004 > a = nil
=> nil
ruby-1.9.2-p180 :005 > b = nil
=> nil
ruby-1.9.2-p180 :006 > GC.start
=> nil
ruby-1.9.2-p180 :007 > ObjectSpace.each_object(C){}
=> 0
因此不再存在对C的引用.好的.但是,用map{|x| x.foo} with map(&:foo)
(广告上是等效的)代替它并不会被收集:
So no references to C exist anymore. Good. But substituting map{|x| x.foo} with map(&:foo)
(which is advertised as equivalent), it doesn't get collected:
ruby-1.9.2-p180 :001 > a = 10.times.map{C.new}
=> [...]
ruby-1.9.2-p180 :002 > b = a.map(&:foo)
=> ["foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo"]
ruby-1.9.2-p180 :003 > ObjectSpace.each_object(C){}
=> 10
ruby-1.9.2-p180 :004 > a = nil
=> nil
ruby-1.9.2-p180 :005 > b = nil
=> nil
ruby-1.9.2-p180 :006 > GC.start
=> nil
ruby-1.9.2-p180 :007 > ObjectSpace.each_object(C){}
=> 10
ruby-1.9.2-p180 :008 >
这是一个红宝石错误吗?我会尝试使用更多版本的ruby来确定,但这似乎是一个明显的问题.有人知道我在做什么错吗?
Is this a ruby bug? I'll try in more versions of ruby to be sure but this seems like an obvious issue. Anyone know what I'm doing wrong?
我已经在1.8.7-p352中进行了尝试,但没有问题. 1.9.3-preview1 确实,但是仍然存在问题.是按顺序报告错误还是我做错了什么?
I've tried this in 1.8.7-p352 and it doesn't have the issue. 1.9.3-preview1 does however still have the issue. Is a bug report in order or am I doing something wrong?
Edit2:格式化(为什么在每行前放置四个空格会产生语法高亮显示,而<pre>
标签却不会?)
formatting (why does putting four spaces before each line produce syntax highlighting while <pre>
tags don't?)
推荐答案
由于a.map(&:foo)
应该与a.map{|x| x.foo}
完全相同,因此看来您确实在Ruby代码中遇到了一个错误.在(http://redmine.ruby-lang.org/)上提交错误报告不会有任何伤害,最糟糕的是它可能会被忽略.您可以通过为该问题提供补丁来减少这种情况的发生.
As a.map(&:foo)
should be the exact equivalent to a.map{|x| x.foo}
, it seems like you really hit a bug in the Ruby code here. It cannot hurt to file a bug report on (http://redmine.ruby-lang.org/), the worst that can happen is that its being ignored. You can decrease the chances of that by providing a patch for the issue.
:我扔了我的IRB,并尝试了您的代码.我可以重现您在ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
上描述的问题.但是,在符号上显式调用to_proc
不会遇到相同的问题:
I threw on my IRB and tried your code. I can reproduce the issue you describe on ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
. However, explicitely calling to_proc
on the symbol does not suffer from the same problem:
irb(main):001:0> class C; def foo; end; end
=> nil
irb(main):002:0> a = 10.times.map { C.new }
=> [...]
irb(main):004:0> b = a.map(&:foo.to_proc)
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
irb(main):005:0> ObjectSpace.each_object(C){}
=> 10
irb(main):006:0> a = b = nil
=> nil
irb(main):007:0> GC.start
=> nil
irb(main):008:0> ObjectSpace.each_object(C){}
=> 0
似乎我们在这里面临隐式Symbol -> Proc
转换的问题.也许以后我会尝试深入探讨Ruby源代码.如果是这样,我会及时通知您.
It seems we are facing an issue with the implicit Symbol -> Proc
conversion here. Maybe I will try to dive a bit into the Ruby source later. If so, I will keep you updated.
该问题的简单解决方法:
Simple workaround for the problem:
class Symbol
def to_proc
lambda { |x| x.send(self) }
end
end
class C
def foo; "foo"; end
end
a = 10.times.map { C.new }
b = a.map(&:foo)
p b
a = b = nil
GC.start
p ObjectSpace.each_object(C) {}
打印0
.
这篇关于Ruby Symbol#to_proc泄漏1.9.2-p180中的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!