2011-08-31 3 views
5

これは私のSinatraアプリでメモリの問題をデバッグする際の2回目の試みです。私はこれを単純なサンプルコードにしたと思います。Rubyシンボル#to_procは1.9.2-p180の参照をリークしますか?

.map(&:some_method)で配列をフィルタリングすると、その配列内の項目がガベージコレクションされないように見えます。等価物を実行すると、.map{|x| x.some_method}は全く問題ありません。

デモンストレーション:簡単なサンプルクラスを考える:私はIRBに次のように実行した場合

class C 
    def foo 
    "foo" 
    end 
end 

、それが正常に収集されます:

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>タグがいない間強調し、各ラインの生産構文の前に4つのスペースを入れない)

答えて

3

a.map(&:foo)としてa.map{|x| x.foo}と完全に同等である必要があり、あなたが本当にのバグを打つように思えますここにRubyコードがあります。バグレポートをhttp://redmine.ruby-lang.org/に提出することはできません。最悪の場合、無視されることがあります。問題のパッチを提供することで、その可能性を減らすことができます。

編集:私はIRBを投げてコードを試しました。 ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]に記載されている問題を再現できます。しかし、明示的に同じ問題に悩まされないシンボルにto_procを呼び出す:私たちがここに暗黙のSymbol -> Proc変換の問題に直面しているようだ

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 

。たぶん私は後でRubyソースにちょっと潜んでみようとします。もしそうなら、私はあなたの更新を続けます。

EDIT 2:問題の

簡単な回避策:

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

+0

私はバグレポートを送信しようとしますが、Ruby redmineのアカウントを設定する際に問題があります。私は彼らがログインシステムに問題がある場合に備えて、後で待つつもりです。 –

+0

私はGoogle Mailを使用しており、確認メールをスパムとしてマークしています。たぶんあなたの迷惑メールフォルダを確認する必要があります:D –

+0

良いコール!彼らは確認メールを送ったことすら知らなかった。とにかく、Bug#5261:http://redmine.ruby-lang.org/issues/5261 –

関連する問題