2010-02-15 19 views
22

En ruby ​​todas las clases son objetos de clase Class. Dado que las clases también son objetos, ¿una máquina virtual de Ruby sigue la misma estrategia de recolección de basura para objetos de clase? ¿Qué determina que un objeto de clase es seguro para la recolección de basura?Ruby Class objeto recolección de basura

Respuesta

0

Cuando no hay nada que vincule al objeto, entonces es seguro deshacerse de él. En cuanto a -cuando- la recolección de basura se lleva a cabo, eso está más allá de mi conocimiento.

+1

Esto es cierto en general, pero las clases se pueden ver como un caso especial. Por ejemplo, si una clase no tiene instancias y no está subclasificada por ninguna otra clase, no tiene 'enlaces' (como dices), pero ¿es realmente seguro para GC? ¿Qué sucede si alguien tiene la intención de construir una instancia en una fecha posterior? No creo que la situación sea tan nítida para las clases como lo haces :) – horseyguy

+0

@banister: Este es exactamente el caso que quería señalar entre otros casos especiales donde un GC podría tener que tratar un objeto de clase en un especial manera –

+1

bastante. Una clase no es más que una constante, ¿no? Y no puede deshacerse de una constante, ya que es una variable dentro de un entorno (incluso si es el objeto 'principal' de IRB, o el tiempo de ejecución), hasta que se completa el entorno. "clase String" es lo mismo que "String = Class.new". – Trevoke

0

No tengo ni idea de cuál es la respuesta, pero ¿no podrías descubrirlo por experimentación? Eche un vistazo al pickaxe. Estoy seguro de que esta es una prueba muy ingenuo, y alguien puede hacer mejor, pero usted consigue la idea:

puts "program start"  
include ObjectSpace 

class SfbdTest 
    def initialize(a) 
     @a = a 
    end 
end 
define_finalizer(SfbdTest, proc{|id| puts "GC on class"}) 

puts "creating instance" 
x = SfbdTest.new(1) 
define_finalizer(x, proc{|id| puts "GC on instance"}) 

puts "zombie-ing instance" 
x = nil 

puts "forcing GC" 
GC.start() 

puts "program end" 

Produce:

[email protected]:~$ ruby -w test.rb 
program start 
creating instance 
zombie-ing instance 
forcing GC 
program end 
GC on instance 
GC on class 
[email protected]:~$ 

parece que necesita un hilo, pero por desgracia Se supone que debo estar trabajando, lo siento ...

1

He probado esto, la respuesta es que parece que sí.

irb(main):001:0> x = [] #Memory Usage = 12MB 
=> [] 
irb(main):002:0> 120000.times {x << Class.new} #Memory usage now at 41 MB 
=> 120000 
irb(main):013:0> x = [] 
=> [] 
irb(main):011:0> GC.start() #Memory usage now at 13MB 
=> nil 
12

Un ejemplo aún más concreto, similar a la respuesta de Andrew Cholakian es el uso de ObjectSpace. Por ejemplo:

2.1.1 :001 > ObjectSpace.count_objects[:T_CLASS] 
=> 884 
2.1.1 :002 > 10000.times { Class.new } 
=> 10000 
2.1.1 :003 > ObjectSpace.count_objects[:T_CLASS] 
=> 20884 
2.1.1 :004 > GC.start 
=> nil 
2.1.1 :005 > ObjectSpace.count_objects[:T_CLASS] 
=> 884 

Esto demuestra que las clases anónimas (no se guardan en una constante en cualquier lugar o utilizados por todas las instancias de esas clases) consigue de hecho el recolector de basura.