web-dev-qa-db-ja.com

Node.jsのアクティブハンドルとは

アプリケーションのアクティブハンドル数が増加し続けていることがわかります。アクティブなハンドルの数は正確には何ですか?これは、アプリのクラッシュを防ぐために注意しなければならないことですか?

11
Balanarayanan

アクティブハンドル

ハンドルは、開かれたファイル、データベース接続、要求などの開かれたリソースへの参照です。ハンドルが閉じられているはずなのに、ハンドルがアクティブである理由を理解するために、簡単な例を示します。

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/secret-url') {
        return; // nobody should have access to this part of our page!
    }

    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World!');
}).listen(3000);

このコードは何をしますか?ポート3000でサーバーを実行し、「シークレットURL」に送信されるものを除いて、すべての要求に対してHello Worldメッセージを返します。しかし、このコードには問題があります。 「秘密の」if句に遭遇したとき、接続を決して閉じません。つまり、クライアントは、必要な限り接続を開いたままにします。代わりに接続を閉じる必要があります。この間違いをすることにより、アクティブハンドルの数が増加し、メモリリークが発生します。

通常、メモリリークは、アクティブハンドルが関数間で渡される可能性があるため、検出がはるかに困難です。これにより、接続を閉じる原因となっているコードを追跡することが困難になります。

アクティブハンドルの数の増加はどういう意味ですか?

開いているハンドルが常に増加している場合は、コードのどこかでメモリリークが発生している可能性があります。例のように、リソースを閉じるのを忘れたかもしれません

Webサーバーのように長時間実行する必要があるスクリプトを開発する場合は、特にメモリリークが非常に悪いです...

メモリリークをチェックする方法は?

メモリリークをチェックするさまざまな手法があります。最も簡単な方法は、明らかにメモリを監視することです。 pm2には、メモリが特定のポイントに達した場合にプロセスを再起動するオプションも組み込まれています。このトピックの詳細については、 このガイド を参照してください。

これは操り人形師と何の関係がありますか?

2つのこと。まず、リクエストは非常に安価です。 Node.jsサーバーアプリケーションでメモリリークが発生した場合でも、数千回のリクエストを行って初めて、メモリリークが発生し始めます。それとは対照的に、操り人形師は非常に高価です。 Chromiumブラウザを開くと、メモリが50〜100メガバイトの範囲で消費されます。したがって、起動するすべてのブラウザが閉じられることを確認する必要があります。第二に、すでに述べた他の回答として、リソースをクリアするために手動で破棄する必要があるオブジェクト( elementHandle など)があります。

6
Thomas Dondorf

Puppeteerには実際にハンドルを使い終わったときに使用するメソッドがあるため、ガベージコレクターはその処理を実行できます。次のようにelementHandle.dispose()を使用することになっています。

const bodyHandle = await frame.$('body');
const html = await frame.evaluate(body => body.innerHTML, bodyHandle);
// Once you're done with you handle just get rid of it
await bodyHandle.dispose();

ドキュメントをチェックしてください:

1
Ramiro