2013-10-23 8 views
6

私のような単純なHTTPサーバーを持っているはず:Node.jsでストリームを使用しているときにメモリリークが発生しましたか?

var http = require('http'); 

http.createServer(function (req, res) { 
    req.on('data', function (data) { 
    console.log('Got some data: ' + data); 
    }); 

    req.on('end', function() { 
    console.log('Request ended!'); 
    }); 

    res.end('Hello world!'); 
}).listen(3000); 

ので、基本的にはデフォルトの101サンプル、今のところ何も特別な - 私はdataと読めるreqストリームのendイベントをサブスクライブすることを除いて。今私はそれらがもはやそれらを必要としなくなったときにそれらのイベントを退会しなければならないかどうか疑問に思う?

または、読み取り可能なストリームが終了すると自動的に消去されますか?

このようなコードでメモリリークが発生する可能性がありますか?

+3

[This](http://stackoverflow.com/questions/5326300/garbage-collection-with-node-js)が役立つかもしれません。 – hexacyanide

+0

これは実際にはより一般的な意味で役立ちました。ありがとうございました:-) –

答えて

15

(この答えはNode.jsのソースコードのrevelant部品へのリンクが含まれています)

あなたの質問に答える前に、のイベントについて話しましょう。これを行うと:

emitter.on('an-event', listener); 

listeneremitterに添付listに追加されます。その後、emitterがイベントをトリガーすると、そのイベントを購読しているすべてのリスナーに、そのリストを繰り返して通知します。 node.jsイベントエミッタの魔法は、あなた自身でそのリストを宣言したり管理したりしないということです。

.on()を呼び出すときはいつでも、back-referenceエミッタ→リスナーを作成します。この参照は、リスナーがGCによって収集されることを防ぎ、決して購読を中止しない場合は "リーク"を作成します。

通常、エミッタはリスナーより先に破壊されるので、node.jsではあまり頻繁には発生しませんが、実際には再接続する時間が長い接続(Twitter Streaming APIと思う) 。イベントの登録を解除しないと、古い接続からイベントが発生し、新しい接続にイベントが適用される可能性があります。これにより、新しい接続が閉じられたと考えることができます。

node.jsは、あなたがリスナーの登録を忘れることを忘れていると思われる場合、悪名高い"possible leak detected"というメッセージを表示します。あなたの例に戻る

:ソケット(REQ + RES)が最初に破壊されてしまうので、

これはリークを作成しません。これはエミッタなので、node.jsはforcibly remove all listenersになります。

+0

エミッターが破壊されたときに、素晴らしい部分がありました。 :-) –

関連する問題