2013-06-17 7 views
8

Rubyで同じJSONファイルを繰り返し解析すると、ますます多くのメモリが使用されるようです。 以下のコードと出力を考えてみましょう。繰り返しJSON解析がますます多くのメモリを消費するのはなぜですか?

  1. 最初の反復後にメモリが解放されないのはなぜですか?
  2. 解析後に116MBのJSONファイルが1.5GbのRAMを占めるのはなぜですか?テキストファイルがハッシュに変換されていることを考えると意外です。私はここで何が欠けていますか?

コード:

require 'json' 

def memused 
    `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1]/1024 
end 

text = IO.read('../data-grouped/2012-posts.json') 
puts "before parsing: #{memused}MB" 
iter = 1 
while true 
    items = JSON.parse(text) 
    GC.start 
    puts "#{iter}: #{memused}MB" 
    iter += 1 
end 

出力:

before parsing: 116MB 
1: 1840MB 
2: 2995MB 
3: 2341MB 
4: 3017MB 
5: 2539MB 
6: 3019MB 
+0

ガベージコレクタは、実行したいときに実行されます。これは、あなたがしたいときには何もしません。 – meagar

+0

プログラムのメモリ不足時にGCを実行するべきではありませんか? jsonが400MBの場合、最初のiterで5ギガのRAMを使用し、後でスワップを使用し始めます(これにより、解析は数秒ではなく数十分かかります)。どのようにGCを呼び出してメモリをきれいにするのですか? – vrepsys

+0

RubyとJSONのどちらのバージョンが使用されていますか? –

答えて

1

RubyはJSONファイルを解析するとき、それは目標を達成するために多くの中間オブジェクトを作成します。これらのオブジェクトは、GCが動作するまでメモリ上にとどまります。

JSONファイルが複雑な構造、多くの配列と内部オブジェクトを持つ場合、その数も急速に増加します。

"GC.start"を呼び出して、Rubyが使用していないメモリをクリーンアップすることを提案しましたか?メモリ量が大幅に減少した場合、データ構造を複雑にするか、libが割り当てを解除できないデータがあります。

大きなJSON処理の場合、yajl-ruby(https://github.com/brianmario/yajl-ruby)を使用します。それは実装されたCであり、実装面積が小さい。

+0

ありがとう、私はそれをやります。しかし、私の質問には答えません。 – vrepsys

+0

@ user1027996私は郵便を編集し、いくつかの情報を含んだ。 –

+0

GC.startを追加しても違いはありません – vrepsys