2

これらは、node.jsの公式ドキュメントからのほんの数行です。

client.on('data', function(data) {
  console.log(data.toString());
  client.end();
});

クライアントオブジェクトにはコールバックへの参照があり、コールバックにはクライアントオブジェクトへのクロージャ参照があると思います。あれは正しいですか?はいの場合、なぜこれが奨励されるのですか?

4

2 に答える 2

3

はい、これは循環参照ですが、メモリ リークではありません。このコード スニペットだけを考えると、少数のオブジェクトの小さなグラフしかありませんが、clientメイン プログラムからアクセスできる限り、これらのオブジェクトのすべてがガベージ コレクションの対象になることはありません。ただし、 を設定すると、オブジェクトと匿名イベント ハンドラー関数をclient = null;含むオブジェクトのグラフは、メイン プログラムから到達できなくなり、ガベージ コレクションの対象となり、A-OK となります。client

このパターン自体はメモリ リークではありません。ループでクライアントを作成し、それらすべてへの参照を配列またはオブジェクトに保持し、古いクライアントを破棄するコードがない場合、はい、それはメモリ リークになります。

于 2013-03-01T14:54:26.097 に答える
1

正解です。node.jsのイベントエミッターは、リスナーをプライベート_listenersプロパティに格納します。ハンドラー関数はclientクロージャー変数として使用しますが、すべてのハンドラーはイベントエミッターをthis参照として呼び出されるため、厳密には必要ありません。

ただし、this代わりにを使用しても、クロージャー内にclientある事実は変更clientされません。使用されていないため、V8がクロージャーから間接参照するようにヒントを与えるだけです。

クロージャから使用された場合でも、V8には、この種の循環参照を処理し、それらをメモリから適切に解放するのに十分なロジックがあります。

于 2013-03-01T14:51:51.307 に答える