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を使用しました、と私は大きな違いを発見していません。
まとめると、私は2つの質問を持っている:
は、いくつかの間隔でメモリをきれいにするために、この通常のGCの動作である、またはそれはいくつかのthreashold代わりの連続クリーニングに到達した後?
.on
のコード例では、メモリ消費グラフに表示されないメモリがリークするはずです。
いくつかの考え...最初の質問については、それは正常です。ガベージコレクションは周期的に実行されます。いくつかのメモリへの参照がなくなると、それはガベージコレクションされる可能性がありますが、そのことがいつ起こるかはわかりません。 2番目の質問については、メモリリークも予想されます。なぜチャートに表示されないのかわかりにくい。 – Tibos
明確にするために、コードを.onceで表示できますか?私はあなたがredisClientでそれをやったと仮定していますが、それはちょうどその時に推測しています。また、私は1で少し高い使用量を参照してください。赤い線..それは 'リーク'ですか?伝説はいいだろう。 onSuccessはすべてのinitRequests間で共有されるため、余分なメモリがほとんど使用されないため、要求がすべて数百万に達する前に終了した場合、はるかに高いピークは期待できません。 – Spork
どのRedisクライアントモジュールを使用しましたか?私は 'RequestObject'を探して面白いものは何も持っていませんでした。 – shawnzhu