2013-09-24 40 views
26

私は約を持っています。6人のSidekiqワーカーは、JSONクロールを実行します。エンドポイントのデータセットのサイズに応じて、1分から4時間で終了します。特に、4時間かかる長いものを見ると、時間の経過とともにメモリがわずかに増加することがわかります。作業者が終了した後にSidekiqがメモリを解放しない

同じ作業者ジョブを再度スケジュールするまでは問題ありません。メモリは、私のSidekiqプロセスを取り除くLinux OOM Killerを実行するまで、割り振られずにスタックされません。

メモリリーク?私は、オブジェクト・スペース内の異なるオブジェクトの数を見て:

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 } 

あっ増加は本当にありません、ハッシュ、配列などのセットが同じ、短い増加はガベージコレクタによって一掃されたままで、gc.stat[:count]を伝えますガベージコレクタも動作しています。

作業者が終了した後でも、 [完了]がログに記録され、ワー​​カーがビジー状態になると、メモリは割り当て解除されません。その理由は何ですか?これに対して何かできますか?ファイナライザを作成しますか?

唯一現在の解決策:Sidekiqプロセスを再開してください。

私はRuby 2.0.0を使用しており、Ruby MRIを使用しています。


JSON解析では、私はYajlを使用してCバインディングを使用します。ストリーミングされた読み書きを適切に実装する唯一の高速JSONパーサーだからです。 Sidekiqを書いた

+1

入力JSONを解析するのにどのような宝石を使用していますか?あなたはC拡張を持つ他の宝石を使っていますか? Rubyオブジェクトを格納するために使用されていないメモリを割り当てているなど、Cの拡張子を持つ宝石からのリークがあるかもしれないように(メモリ使用量は増えますが、Rubyオブジェクトの数は一定です)それを決して解放しない)。 – grumbler

+4

オブジェクトを繰り返し変更し、新しいオブジェクトを割り当てずにサイズを拡大させる、純粋なRubyの「リーク」がある可能性もあります。たとえば、Ruby Stringに繰り返し追加すると、オブジェクトの数を増やすことなく、継続的に多くのメモリを消費します。 – grumbler

+1

@ grumblerああ良い点。私は自分の疑問を広げた。私はYajlをJSON解析に使用しています。これは確かにCバインディングです。これについては決して考えなかった。 –

答えて

8

マイクPerhamのは、ここでこれを取り上げ:http://www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/

TL; DRのバージョン: MRIが戻ってメモリを与えることはありません、ほとんどあなたが行うことができますが、ヒープを制御し、それを行うことです、 Ruby Enterprise Editionが提案されました。

これはいずれも役立ちますが、それは馬の口からまっすぐな状況です。

+1

ニースポインタ@digitalextremist +1 – Rohit

+1

これは面白いです、ありがとう:) –

+9

古いスレッド、私は知っているが、これがRuby 2.1にも当てはまり、新しいGCであるかどうかは分かりますか? –

関連する問題