好的,这是我第二次尝试使用 Sinatra 应用程序调试内存问题。我相信这次我已经将其固定为简单的示例代码。
看来当我过滤数组时.map(&:some_method)
,它会导致该数组中的项目无法被垃圾收集。运行等效的.map{|x| x.some_method}
完全没问题。
演示:给定一个简单的示例类:
class C
def foo
"foo"
end
end
如果我在 IRB 中运行以下命令,它会正常收集:
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)
(这被宣传为等效),它不会被收集:
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 来确定,但这似乎是一个明显的问题。有人知道我做错了什么吗?
Edit:
我在 1.8.7-p352 中尝试过,没有问题。 1.9.3-预览1does但仍然存在问题。错误报告是否正常,或者我做错了什么?
Edit2:格式化(为什么在每行之前放置四个空格会产生语法突出显示,而<pre>
标签没有?)