【发布时间】:2011-08-31 20:53:12
【问题描述】:
好的,这是我第二次尝试调试我的 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 来确定,但这似乎是一个明显的问题。有谁知道我做错了什么?
编辑:
我已经在 1.8.7-p352 中尝试过,但没有问题。 1.9.3-preview1 确实但是仍然有问题。是按顺序报告错误还是我做错了什么?
Edit2:格式化(为什么在每行前放置四个空格会产生语法高亮,而 <pre> 标记不会?)
【问题讨论】:
标签: ruby memory-leaks