GC用プロファイラ作った!

どういうもの?

GC.profile = true

# 計測対象の処理

GC.display 

ってすると

---- 以下のプロファイル情報が出力される ----- 
GC 10 invokes.
Index       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
    0               338620               360448                18018         0.00000000000000014129
    1               605620               622592                31122         0.40010000000000001119
    2              1080300              1097728                54873         0.00000000000000007657
    3              1931420              1949696                97461         0.40000000000000018874
    4              3470040              3489792               174447         0.40010000000000034426
    5              6236220              6258688               312858         1.19999999999999906741
    6             11212100             11239424               561834         2.00009999999999976694
    7             20181760             20217856              1010646         3.60029999999999850147
    8             36320600             36372480              1818180         6.80040000000000244285


2008275 used objects 80 free objects and 2008355 total objects in Heap.
Index                Count                    %          Kind (class)
    1              1500000          74.68799092                Child
    2               500000          24.89599697               Parent
    3                 5974           0.29745737               Object
    4                 1644           0.08185804               String
    5                  416           0.02071347                Class
    6                   81           0.00403315             Encoding
    8                   47           0.00234022 RubyVM::InstructionSequence
    9                   19           0.00094605               Module
   10                   17           0.00084646                Array
   11                   16           0.00079667                 Hash
   12                   14           0.00069709                Float
   13                   10           0.00049792               Regexp
   14                    9           0.00044813           Enumerable
   15                    5           0.00024896           Comparable
   16                    3           0.00014938                   IO
   17                    3           0.00014938            Precision
   18                    2           0.00009958               Bignum
   19                    1           0.00004979              Complex
   20                    1           0.00004979               Thread
   21                    1           0.00004979               RubyVM
   22                    1           0.00004979          ThreadGroup
   23                    1           0.00004979        NoMemoryError
   24                    1           0.00004979              Binding
   25                    1           0.00004979     SystemStackError
   26                    1           0.00004979          RubyVM::Env
   27                    1           0.00004979                Mutex
   28                    1           0.00004979      File::Constants
   29                    1           0.00004979           ARGF.class
   30                    1           0.00004979     Gem::QuickLoader
   31                    1           0.00004979                 Data
   32                    1           0.00004979                fatal
   33                    1           0.00004979               Kernel

------ ここまで ------ 

ってな事が可能。
 
超絶便利だよね!!
 

Hashでくれ

データをHashでくれよ。
グラフとかにしたいからさぁー。
とかいうニーズは必然ですね。

GC.report
=>[{:GC_TIME=>0.004, :HEAP_USE_SIZE=>340800, :HEAP_TOTAL_SIZE=>360448, :HEAP_TOTAL_OBJECTS=>18018},
{:GC_TIME=>0.004, :HEAP_USE_SIZE=>605640, :HEAP_TOTAL_SIZE=>622592, :HEAP_TOTAL_OBJECTS=>31122},
{:GC_TIME=>0.004, :HEAP_USE_SIZE=>1080320, :HEAP_TOTAL_SIZE=>1097728, :HEAP_TOTAL_OBJECTS=>54873},
{:GC_TIME=>0.004, :HEAP_USE_SIZE=>1931440, :HEAP_TOTAL_SIZE=>1949696, :HEAP_TOTAL_OBJECTS=>97461},
{:GC_TIME=>5.8885730493119e-18, :HEAP_USE_SIZE=>3470060, :HEAP_TOTAL_SIZE=>3489792, :HEAP_TOTAL_OBJECTS=>174447},
{:GC_TIME=>0.012001, :HEAP_USE_SIZE=>6236240, :HEAP_TOTAL_SIZE=>6258688, :HEAP_TOTAL_OBJECTS=>312858},
{:GC_TIME=>0.020001, :HEAP_USE_SIZE=>11212120, :HEAP_TOTAL_SIZE=>11239424, :HEAP_TOTAL_OBJECTS=>561834},
{:GC_TIME=>0.036003, :HEAP_USE_SIZE=>20181780, :HEAP_TOTAL_SIZE=>20217856, :HEAP_TOTAL_OBJECTS=>1010646},
{:GC_TIME=>0.068004, :HEAP_USE_SIZE=>36320620, :HEAP_TOTAL_SIZE=>36372480, :HEAP_TOTAL_OBJECTS=>1818180}]

ObjectSpace.count_classes
=>{:TOTAL=>2009174, :FREE=>304, :Object=>5992, :Child=>1500000, :Parent=>500000, :String=>1991, :Array=>88, :Regexp=>10,
 :"Gem::QuickLoader"=>1, :Hash=>29, :Class=>416, :Module=>19, :"RubyVM::InstructionSequence"=>47, :Encoding=>81, :Mutex=>1,
 :"RubyVM::Env"=>1, :Binding=>1, :Complex=>1, :Precision=>3, :ThreadGroup=>1, :Thread=>1, :RubyVM=>1, :Enumerable=>9, :NoMemoryError=>1,
 :Float=>160, :SystemStackError=>1, :Bignum=>2, :Comparable=>5, :"File::Constants"=>1, :"ARGF.class"=>1, :IO=>3, :Data=>1, :fatal=>1, :Kernel=>1}

まぁ素敵。
 

メリット

  • メモリリークの調査が簡単になる
    • どのクラスが多く生成されているかよく分かり、調査しやすい。
    • 現在RubyレベルからHeap内部のクラス名による統計情報を取得する方法は無い(調査しずらかった)
    • 便利じゃないでしょうか?

 

  • パフォーマンスチューニングしやすい
    • GCの実行時間を手軽に測れる
    • GCによるHeapサイズの変動を見ることができ、パフォーマンスチューニングがしやすい。

(関係ないけどJavaのjconsoleとかすっごくいいよね!!JavaGCかわいい!!)
 

助けてください!

結構幸せ度は高そうなんですけど、僕はGC完全に偏った男なので判断できる目を持っておりません。
何か意見があればruby-devへ