2011-08-31 10 views
5

Bien, este es mi segundo intento de depurar los problemas de memoria con mi aplicación Sinatra. Creo que lo tengo encriptado en código de muestra simple esta vez.Ruby Symbol # to_proc filtra referencias en 1.9.2-p180?

Parece que al filtrar una matriz a través de .map(&:some_method), hace que los elementos de esa matriz no se recojan basura. Ejecutar el equivalente .map{|x| x.some_method} es totalmente correcto.

Demostración: Dada una clase de ejemplo simple:

class C 
    def foo 
    "foo" 
    end 
end 

Si me quedo en la siguiente IRB, sea recolectado normalmente:

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 

Así que no hay referencias a C existe más. Bueno. Pero sustituyendo map{|x| x.foo} with map(&:foo) (que se anuncia como equivalente), que no consigue recogido:

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 > 

Es esto un error de rubí? Voy a probar en más versiones de ruby ​​para estar seguro, pero esto parece ser un problema obvio. ¿Alguien sabe lo que estoy haciendo mal?

Editar:

He intentado esto en 1.8.7-P352 y no tiene el problema. 1.9.3-preview1 does Sin embargo, todavía tiene el problema. ¿Hay un informe de error en orden o estoy haciendo algo mal?

Edit2: formatear (¿por qué no poner cuatro espacios antes de cada sintaxis de la línea de productos, mientras que destaca <pre> etiquetas no lo hacen)

Respuesta

3

Como a.map(&:foo) debe ser el equivalente exacto a a.map{|x| x.foo}, parece como si realmente golpea un error en el código de Ruby aquí. No tiene sentido presentar un informe de error en (http://redmine.ruby-lang.org/), lo peor que puede pasar es que se ignore. Puede disminuir las posibilidades de eso al proporcionar un parche para el problema.

EDIT: Lancé mi IRB e intenté con su código. Puedo reproducir el problema que describes en ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]. Sin embargo, explícitamente llamando to_proc en el símbolo no sufre el mismo problema:

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 

Parece estamos frente a un problema con la conversión implícita Symbol -> Proc aquí. Tal vez intente bucear un poco en la fuente de Ruby más tarde. Si es así, te mantendré actualizado.

EDIT 2:

solución simple para el problema:

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

impresiones 0.

+0

Voy a tratar de enviar un informe de error pero estoy teniendo problemas para configurar una cuenta en el redmine Ruby. Esperaré hasta más tarde en caso de que tengan problemas con su sistema de inicio de sesión. –

+0

Estoy usando Google Mail y marcó su correo de confirmación como correo no deseado. Tal vez deberías revisar tu carpeta de spam: D –

+0

¡Buena llamada! No tenía idea de que incluso enviaron un correo de confirmación. De todos modos, Bug # 5261: http://redmine.ruby-lang.org/issues/5261 –

Cuestiones relacionadas