2011-08-31 11 views
5

Tamam, bu benim Sinatra uygulamam ile bellek sorunları hata ayıklamada ikinci denemedir. Bu sefer basit örnek kodlara başvurduğumu düşünüyorum.Ruby Symbol # to_proc, 1.9.2-p180'deki referanslara sızıyor mu?

Bir diziyi .map(&:some_method) aracılığıyla filtrelediğimde, bu dizideki öğelerin çöp toplanmamasına neden oluyor. Eşdeğer .map{|x| x.some_method}'u çalıştırmak tamamen iyi.

Gösteri: Basit bir örnek sınıfın Verilen:

class C 
    def foo 
    "foo" 
    end 
end 

ben IRB aşağıdaki çalıştırırsanız

, normal toplanan alır:

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 

Yani C'ye hayır referanslar artık mevcut. İyi. Ama (eşdeğer olarak duyurulan) map{|x| x.foo} with map(&:foo) yerine, bu toplanan almaz:

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 > 

bu bir yakut hata mı? Emin olmak için daha fazla ruby ​​versiyonunu deneyeceğim ama bu bariz bir konu gibi görünüyor. Neyi yanlış yaptığımı bilen var mı?

Düzenleme:

Ben 1.8.7-p352 bu denedim ve sorunu yoktur. 1.9.3-preview1 ,'u hala yapıyor, ancak yine de sorun var. Bir hata raporu düzenli mi yoksa yanlış bir şey mi yapıyorum?

Edit2: biçimlendirme (? Neden <pre> etiketleri yok ederken vurgulayarak her satırı üreten sözdizimi önce dört boşluk koyarak etmez)

cevap

3

a.map(&:foo) gibi a.map{|x| x.foo} için tam denk olmalıdır, gerçekten sen bir hata vurmak gibi görünüyor Ruby kodu burada. (Http://redmine.ruby-lang.org/) hakkında bir hata raporu yazmak zarar veremez, olabilecek en kötü şey göz ardı edilmemesidir. Bu konuya ilişkin bir yama sağlayarak bu şansı azaltabilirsiniz.

DÜZENLEME: IRB'mi attım ve kodunuzu denedim. ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]'da açıkladığınız sorunu yeniden oluşturabilirim. Ancak, açık bir şekilde aynı sorundan muzdarip değildir simgesine to_proc arayarak: Biz burada örtük Symbol -> Proc dönüşümüyle bir sorun karşı karşıya görünüyor

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 

. Belki birazdan Ruby kaynağına dalmaya çalışacağım. Eğer öyleyse, seni güncel tutacağım.

DÜZENLEME 2: sorun için

Basit geçici çözüm:

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) {} 

baskılar 0.

+0

Bir hata raporu göndermeyi denerim ancak Ruby redmine'de bir hesap oluşturmada sorun yaşıyorum. Giriş sistemiyle ilgili sorun yaşadıklarında daha sonra bekleyeceğim. –

+0

Google Mail kullanıyorum ve onay postalarını spam olarak işaretledim. Belki de spam klasörünüzü kontrol etmelisiniz: D –

+0

İyi çağrı! Onay postası bile göndermediklerini bilmiyordum. Her neyse, Hata # 5261: http://redmine.ruby-lang.org/issues/5261 –

İlgili konular