簡體   English   中英

GC.start 似乎並沒有真正收集垃圾

[英]GC.start doesn't seem to actually collect the garbage

我正在開發一個具有終結器方法的類。 為了測試該類,我想運行垃圾收集器,然后測試一些狀態以查看是否一切正常。 但是,我似乎無法真正收集垃圾,因此在腳本結束之前不會發生最終確定。 以下代碼顯示了問題。

class FinalCall
    def initialize
        ObjectSpace.define_finalizer(self, proc { puts 'finalizing' })
    end
end

FinalCall.new
GC.start
puts 'done'

我曾期待這樣的輸出:

finalizing
done

但我實際上得到了這個:

done
finalizing

我錯過了什么? 您如何強制 GC 完成超出范圍的所有內容?

GC.start不能保證垃圾收集器會運行。 如果 GC 發生在這個特定的時間點,這只是一個建議,對您的代碼來說是可以的。 要求 GC 在特定時間點運行會不合理地限制實現者。 例如,不可能為 JVM、CLI、ECMAScript 或 PyPy 平台編寫 Ruby 實現,或者使用 Eclipse OMR 等框架,因為 GC 不受實現者的控制。

無法保證 GC 何時發生。 甚至沒有一個保證,一個GC會發生在所有

因此,也無法保證終結器何時或是否會運行。

雖然 Jörg 是正確的,但這里還有一個額外的問題:你的終結器 proc 創建一個對self的閉包,它增加了引用計數,然后阻止你的對象被收集!

正確的方法是使用一個類方法來創建一個不會關閉實例的過程。 例如:

class IncorrectFinalCall
  def initialize
    ObjectSpace.define_finalizer( self, proc { puts 'finalizing IncorrectFinalCall' } )
  end
end

class FinalCall
  def initialize
    ObjectSpace.define_finalizer( self, self.class.finalizer )
  end

  def self.finalizer
    proc { puts 'finalizing FinalCall' }
  end
end

10.times do
  IncorrectFinalCall.new
  FinalCall.new
end
GC.start
puts 'done'

導致:

ruby gc.rb
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
finalizing FinalCall
done
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall
finalizing IncorrectFinalCall

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM