SlideShare a Scribd company logo
本当は怖い
         ObjectSpace.each_object
                             nari(中村)
                          ネットワーク応用通信研究所



Powered by Rabbit 0.5.7
自己
紹介
自己紹介
 nariと申します
 九州Ruby01会議でGCについて喋ったもの
 です
 はてなで「I am Cruby」というブログ
 福岡出身の島根県民
   島根は鳥取の左です!
   (大事な事なので二回言いました)
                          2/67
ObjectSpace.each_object
超基本的
 な疑問
ObjectSpace.each_object
       って何?
Heap内にある
全てのオブジェクト(一部除く)に対して
ObjectSpace.each_object
      {|o| puts o }
ObjectSpace.each_object
      {|o| puts o }
引数に渡した
ブロックの処理を行う
例えば
こんな処理が書ける
Heap内のオブジェクトを全
      てpする
特定のクラスのみをダンプ
     する.
Heap内のクラス数の統計を
       取る
こ,これは便利!
仕組み
単純にHeap内を一つ一つな
めていく




             16/67
オブジェクトがあれば処理を
評価




            17/67
次へ




     18/67
なるほど...
と言う事は...
こ,こんなコードも動く?
デモ
Ruby内部では
処理を評価&やる夫生成




              24/67
次へ,処理を評価&やる夫
生成




           25/67
次へ,やる夫登場&やる夫
生成




           26/67
次へ,やる夫登場&やる夫
生成




           27/67
次へ,やる夫登場&やる夫
生成




           28/67
結果
やる夫が増殖!




          30/67
こっ,これは完全に
Ruby暗黒面ですね!
ここで疑問
『これって,処理中に
オブジェクトを生成しても何
 でフリーズしないの?』
つまりさっきの様に
処理時にオブジェクト生成




               35/67
処理時にオブジェクト生成




               36/67
処理時にオブジェクト生成




               37/67
処理時にオブジェクト生成




               38/67
処理時にオブジェクト生成




               39/67
無限ループへ...




            40/67
って事になぜならないの
    か?
理由
GC
可愛いよGC!
オブジェクトがあれば処理を
評価




            44/67
その処理内でオブジェクト生
成




            45/67
そのオブジェクトで処理を評
価




            46/67
その処理内でオブジェクト生
成




            47/67
ヒープがいっぱいになったら
GC発動!




            48/67
ゴミが回収されて無限ループ
回避




           49/67
GCによって無限ループを
   回避していた.
なのでGC.disable=trueにす
       ると
デモ
返ってこない!
GCが動かないので無限に
オブジェクトが生成されてし
     まった
ちなみにさっきのHeap内の
  統計を取ったものは
正確な値じゃない
デモ
このような場合,Ruby1.9で
           は
ObjectSpace.count_objects
      があります.
最後に
実際にある
 悪用例
デンマーク出身のDHHさん
の場合




            61/67
あるクラスのサブクラスを取
得する
  class Object
    def subclasses_of(*superclasses)
      subclasses = []
      superclasses.each do |sup|
        ObjectSpace.each_object(class << sup; self; end) do |k|
          if k != sup &&
            (k.name.blank? ||
               eval(quot;defined?(::#{k}) &&
                 ::#{k}.object_id == k.object_idquot;))
            subclasses << k
          end
        end
      end
      subclasses
    end
  end



                                                                  62/67
使うときは
  class Fizz; end
  class Buzz < Fizz; end
  class FizzBuzz < Fizz; end
  subclasses_of(Fizz) #=> [Buzz, FizzBuzz]




                                             63/67
これだけの為にヒープ全て
  をブン回す!!!
ActiveSupport
に入ってます.
まとめ
 ObjectSpace.each_objectは完全な暗黒面で
 す.
 大事な場面では使わないようにしましょう.
 どうでもいいような所で使いましょう.
   例えばデバッグとかデバッグとか




                              66/67
ご静聴
ありがとうございました.

More Related Content

本当は怖いObjectSpace.each_object