DestructorはないけどFinalizerはあった件
http://d.hatena.ne.jp/komamitsu/20090422/1240413644で
コードの違いからするとガベコレのタイミングでTCP close()しているようにも思えるけど、Rubyではデストラクタがないからなぁ… どうやってるんだろう?
って書いたのだけど、そこ「ガベコレのタイミング」だったら対応するのは「Finalizer」だYO!!! > 自分
ということでRubyにはObjectSpace.define_finalizerがあるのでした。
こんなコードを書いて…
class Demo def self.cleanup lambda {puts "finalized!"} end def initialize @a = "abcdefg" * 1024 * 1024 * 2 ObjectSpace.define_finalizer(self, self.class.cleanup) end end 1.upto 8 do |i| puts Time.now Demo.new sleep 1 end
はしらせてみると
komamitsu@potato:~/lab/ruby$ ruby fin.rb Sun Apr 26 22:04:49 +0900 2009 Sun Apr 26 22:04:50 +0900 2009 Sun Apr 26 22:04:51 +0900 2009 finalized! finalized! Sun Apr 26 22:04:52 +0900 2009 Sun Apr 26 22:04:53 +0900 2009 Sun Apr 26 22:04:54 +0900 2009 Sun Apr 26 22:04:55 +0900 2009 Sun Apr 26 22:04:56 +0900 2009 finalized! finalized! finalized! finalized! finalized! finalized!
となる。
注意すべき点としては、ObjectSpace.define_finalizerで渡しているProcインスタンスからDemoインスタンスへの参照が残らないように気をつけること。あと、私の環境だとDemoの@aのサイズが小さいとガベージコレクションで回収されないみたいだったので無駄に大きくしています。