1

動画ファイルの転送に websockets を使用しています。これは、動画ファイルが大きいことを意味します。サーバー側 (およびクライアント側も) は nodejs を使用して実装され、javascript で binaryjs が使用されます。

多数のクライアントを持ち始めるまでは問題なく機能し、サーバーがクラッシュしました(プロセスはLinux OSによって強制終了されました)。私が観察したように、すべてのクライアントで大量のメモリを使用しているため、メモリが不足していますが、クライアントが切断されても、このメモリは解放されません。これは内部で行うべきであり、メモリについて心配する必要はないと思いますが、間違っていますか? 私は何か間違ったことをしているかもしれませんか?

私が見たように、その「送信」機能は、送信する必要があるものを保存するためにメモリを予約していますが、解放することはありません。(その行にコメントを付ければ、メモリの問題はありません) コードは次のとおりです。

var fs = require('fs');
var BinaryServer = require('binaryjs').BinaryServer;
var bs = BinaryServer({port: 8080});

var nchunks=116;

bs.on('connection', function(client){
for(var i=1; i<=nchunks; i++)
{
    var name="/var/www/1.m4s";
    var fd=fs.openSync(name.replace("1.m4s", i+".m4s"), 'r');
    var buf = new Buffer(fs.fstatSync(fd).size, 'binary');
    fs.readSync(fd, buf, 0, buf.length, null)
    client.send(buf);
    fs.closeSync(fd);

    if(i==nchunks){
        client.send("end"); 
    }
}
client.on('close', function(c){
    console.log("closing");
});

});

クライアントがすべてのビデオファイルを受信すると、ソケットが閉じられるため、サーバーで「閉じる」イベントをキャプチャしているため、ソケットが閉じられていることがわかります。この時点でメモリを解放するべきではありませんか?

最悪なのは、エラーが見つからなかったので、binaryjs の実装方法が原因かもしれないと思ったので、「ws」と「websocket-node」でも試してみましたが、同じ結果がメモリにありました。

誰もこの問題を経験しましたか? 何か案が?

4

1 に答える 1

2

この時点でメモリを解放するべきではありませんか

いいえ、JavaScript はガベージ コレクション言語であり、ガベージ コレクタはランタイムが適切と判断した場合に定期的に実行されます。いつ、または実行されるかどうかを制御したり認識したりできないため、メモリが解放されます。

また、ネットワーク サーバーで同期 IO 呼び出しを使用することはできません。これらの IO 呼び出しを実行している間、すべてのクライアント処理がブロックされるからです。

あなたの主な問題は、ファイルを適度に小さなチャンクでストリーミングしていないことだと思います。ファイル全体をメモリに読み込んで送信しようとしています。

var buf = new Buffer(fs.fstatSync(fd).size, 'binary');

そうしないでください。ReadableStream を使用し、一連の小さなチャンクでファイルを送信し、非同期呼び出しを使用します。これは、ノードを正しく機能させる方法です。ストリーミングの欠如と非同期呼び出しの欠如は、確実にノードの失敗への道です。これが実際のプログラム例です。

var fs = require("fs");
var http = require("http");
var server = http.createServer();
server.listen(9200)
server.on('request', function (req, res) {
  fs.createReadStream('/tmp/test1').pipe(res);
});

ノード v0.10.7 を使用して OSX でこれをテストしたところ、ファイルを繰り返し要求でき、ファイルが適切に開いたり閉じたりするのcurl localhost:9200 >/dev/nullを見るlsof -p <pid of node>ことができます。/tmp/test

于 2013-05-23T22:02:30.190 に答える