2010-02-15 269 views
22

在ruby中,所有的類都是Class類的對象。由於類也是對象,Ruby VM是否遵循類對象的垃圾收集策略?什麼決定了一個類對象對於垃圾收集是安全的?Ruby類對象垃圾回收

回答

0

當沒有任何東西鏈接到對象時,可以安全地擺脫它。至於 - 當垃圾收集運行時,這超出了我的理解。

+1

這在一般情況下是正確的,但類可以被視爲一種特殊情況。例如,如果一個類沒有實例,並且沒有被任何其他類所繼承,那麼它就沒有「鏈接」(就像你說的那樣),但是GC真的很安全嗎?如果有人打算在日後從其構建實例,該怎麼辦?我認爲這種情況並不像你所說的那樣清晰:) – horseyguy

+0

@banister:這正是我想指出的,在其他特殊情況下,GC可能不得不在特殊的對象中處理類對象方式 –

+1

夠公平的。 一個班只不過是一個常數,不是嗎? 你不能擺脫一個常量,因爲它是一個環境中的變量(即使它是IRB的'主要'對象,或運行時),直到環境完成。 「class String」與「String = Class.new」是一樣的。 – Trevoke

0

我不知道答案是什麼,但可以通過實驗找不到嗎?看看pickaxe。我敢肯定,這是一個非常幼稚的測試,有人可以做的更好,但你的想法:

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" 

產地:

[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]:~$ 

看起來像它需要一個線程,但不幸的是我應該是工作,對不起...

1

我測試了這一點,答案是它看起來像它。

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

一個更具體的例子,類似於Andrew Cholakian的回答是使用ObjectSpace。例如:

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 

這表明匿名類(未保存在一個恆定的任意位置,或這些類的任何實例使用)確實得到垃圾收集。