これらは、node.jsの公式ドキュメントからのほんの数行です。
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
クライアントオブジェクトにはコールバックへの参照があり、コールバックにはクライアントオブジェクトへのクロージャ参照があると思います。あれは正しいですか?はいの場合、なぜこれが奨励されるのですか?
これらは、node.jsの公式ドキュメントからのほんの数行です。
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
クライアントオブジェクトにはコールバックへの参照があり、コールバックにはクライアントオブジェクトへのクロージャ参照があると思います。あれは正しいですか?はいの場合、なぜこれが奨励されるのですか?
はい、これは循環参照ですが、メモリ リークではありません。このコード スニペットだけを考えると、少数のオブジェクトの小さなグラフしかありませんが、client
メイン プログラムからアクセスできる限り、これらのオブジェクトのすべてがガベージ コレクションの対象になることはありません。ただし、 を設定すると、オブジェクトと匿名イベント ハンドラー関数をclient = null;
含むオブジェクトのグラフは、メイン プログラムから到達できなくなり、ガベージ コレクションの対象となり、A-OK となります。client
このパターン自体はメモリ リークではありません。ループでクライアントを作成し、それらすべてへの参照を配列またはオブジェクトに保持し、古いクライアントを破棄するコードがない場合、はい、それはメモリ リークになります。
正解です。node.jsのイベントエミッターは、リスナーをプライベート_listenersプロパティに格納します。ハンドラー関数はclient
クロージャー変数として使用しますが、すべてのハンドラーはイベントエミッターをthis
参照として呼び出されるため、厳密には必要ありません。
ただし、this
代わりにを使用しても、クロージャー内にclient
ある事実は変更client
されません。使用されていないため、V8がクロージャーから間接参照するようにヒントを与えるだけです。
クロージャから使用された場合でも、V8には、この種の循環参照を処理し、それらをメモリから適切に解放するのに十分なロジックがあります。