2014-01-16 16 views
17

node.jsアプリケーションで、コードが想定していたメモリリークを探して、いくつかのテストを行いました。私は私の意見では記憶を漏らすべきスクリプトを実行するが、私は結果に驚いている。Node.js(v8)ガベージコレクタはどのように機能しますか?

redisClient.on('message', initRequest); 


function onSuccess(self, json){ 

    console.dir(json); 

} 


function initRequest(channel, message){ 

    var request = new RequestObject({ 

    redisMessage: message 

    }); 

    request.on('success', onSuccess); 

} 

redisClientは、1秒間に数回の 'メッセージ'イベントを放出します。つまり、initRequest関数がかなり頻繁に呼び出されます。 requestオブジェクトがメモリ内に作成されるたびに、関数onSuccessが 'success'イベントにバインドされます。

このオブジェクトにリスナー(この場合はonSuccess)がバインドされている限り、ガベージコレクションはできません。それで、私はメモリが自由になることはないので、メモリ使用量は増加すると思った。

この潜在的なリークの解決策として、.onの代わりに.onceを使用しました。リスナーのバインドが解除され、オブジェクトがガベージコレクションされる可能性があるためです。

私は(.on.onceと1ここで言及する価値はない別のシナリオを比較する)両方のシナリオをテストするためにのpmapを使用しました、と私は大きな違いを発見していません。

enter image description here

まとめると、私は2つの質問を持っている:

  1. は、いくつかの間隔でメモリをきれいにするために、この通常のGCの動作である、またはそれはいくつかのthreashold代わりの連続クリーニングに到達した後?

  2. .onのコード例では、メモリ消費グラフに表示されないメモリがリークするはずです。

+1

いくつかの考え...最初の質問については、それは正常です。ガベージコレクションは周期的に実行されます。いくつかのメモリへの参照がなくなると、それはガベージコレクションされる可能性がありますが、そのことがいつ起こるかはわかりません。 2番目の質問については、メモリリークも予想されます。なぜチャートに表示されないのかわかりにくい。 – Tibos

+0

明確にするために、コードを.onceで表示できますか?私はあなたがredisClientでそれをやったと仮定していますが、それはちょうどその時に推測しています。また、私は1で少し高い使用量を参照してください。赤い線..それは 'リーク'ですか?伝説はいいだろう。 onSuccessはすべてのinitRequests間で共有されるため、余分なメモリがほとんど使用されないため、要求がすべて数百万に達する前に終了した場合、はるかに高いピークは期待できません。 – Spork

+0

どのRedisクライアントモジュールを使用しましたか?私は 'RequestObject'を探して面白いものは何も持っていませんでした。 – shawnzhu

答えて

5

1::-)はい

2:一般的にメモリのリークイベントリスナーを使用していること放出されるオブジェクトが保っているので、ガベージコレクションを防止することがリッスンしているオブジェクトそれへの参照。

あなたのコードではonSuccess機能がrequestオブジェクトによって参照されます。ただし、onSuccessは、すべての要求オブジェクトのリスナーとして再利用される関数の1つで、メモリが増えることはありません。

追記:私はredisClientRequestObjectの内臓を知らないが、requestとすぐinitRequest機能が完了すると、ガベージコレクションのための準備が整いますように私にも見えるが、そのリスナーのいずれかが呼び出される前に、それは可能性があります。

+0

私のコンサーは、誰が誰を参照しているのかという間違った仮定から来たようです。今私はイベントのemmiterがリスナーを参照していると反対の方法ではないことを理解しています。 –

2

私の知る限り、要求オブジェクトはinitRequest関数内にのみ存在する必要があります。そのため、関数が終了するとガベージコレクションのためにマークする必要があります。

関連する問題