クラスのアンロードがうまく出来ません
うーん、クラスがうまくアンロードできません。クラスやモジュールがGCの対象となるのは、
http://www.rubyist.net/~matz/20061227.html#p06
- そのクラス/モジュールを指す定数が削除され(remove_const)
- そのクラス/モジュールを利用するクラスが存在せず
- そのクラスのインスタンスが存在しない
という三条件が揃っている時、というのは分かっているのですが、これを満たしているつもりの以下のコードではなぜかクラスのアンロードに失敗します。
GC.enable class ABC; end Object.class_eval{ remove_const :ABC } GC.start ObjectSpace.each_object(Class){|obj| p obj if obj.name == 'ABC' # => ABC }
なにが悪いのでしょうか。remove_constで :ABC は削除してるし、ABCを利用しているクラスやモジュールはなく、ABCのインスタンスもない。と思うのですが、実際には私が気付いていないだけでなにかがABCを参照しているのでしょうか。
でも、これと同じのをirbでやると、確かにアンロードされるんだけどなぁ。
追記
やっぱり基本的にはアンロードされる条件を満たしているような気がします。
GC.enable class C1; end class C2; end class C3; end class C4; end class C5; end $list = [] ObjectSpace.each_object(Class){|obj| $list << obj.name } Object.class_eval{ remove_const :C1 remove_const :C2 remove_const :C3 remove_const :C4 remove_const :C5 } GC.start ObjectSpace.each_object(Class){|obj| $list.delete_if{ |c| c == obj.name } } p $list p $list.size
これを"ruby 1.8.6 (2007-06-07 patchlevel 36) [i486-linux]"で実行してみると結果は次のようになります。
["C4", "C3", "C2", "C1"] 4
また"ruby 1.8.6 (2008-03-03 patchlevel 114) [i686-linux]"で実行してみると。
["C3", "C2", "C1"] 3
さらに"ruby 1.9.0 (2008-03-14 revision 0) [i686-linux]"で実行してみると。
[] 0
というわけで、結果はただの気紛れなんじゃないのか、という気がします。とにかく一応、GCされないこともないことが分かったので、これで良しとします。