Node.js

时间:2018-02-08 17:56:06

标签: node.js pm2 puppeteer

我看到我的应用程序活动句柄数不断增加。活动句柄的数量究竟是多少?这是我必须要注意防止应用程序崩溃吗?

2 个答案:

答案 0 :(得分:2)

活动手柄

句柄是对打开的资源(例如打开的文件,数据库连接或请求)的引用。要了解为什么句柄应该已经关闭但为什么它们仍处于活动状态,所以我举一个简单的例子:

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上运行服务器,并为任何请求返回一条Hello World消息,但去“秘密URL”的请求除外。但是这段代码有问题。当我们遇到“秘密” if子句时,我们永远不会关闭连接。这意味着客户端将根据需要保持打开连接的时间。相反,我们应该关闭连接。通过犯此错误,活动句柄的数量将增加,从而导致内存泄漏。

通常,内存泄漏很难检测到,因为活动句柄可能会从一个函数传递到另一个函数,这使得很难跟踪哪个代码负责关闭连接。

活动句柄数量的增加意味着什么?

如果看到打开句柄的数量不断增加,则很可能代码中的内存泄漏。像在示例中一样,您可能忘记了关闭资源

如果您打算开发应该长时间运行的脚本(例如Web服务器),则内存泄漏尤其严重。

如何检查内存泄漏?

有多种技术可以检查内存泄漏。最简单的方法显然是关注内存。 pm2甚至有一个内置选项,以防万一内存达到特定点时重新启动该过程。有关此主题的更多信息,请查看this guide

这与木偶戏有什么关系?

两件事。首先,请求非常便宜。即使您的Node.js服务器应用程序中发生内存泄漏,您也只会在数千次请求后才开始在内存中看到它。与此相反,木偶戏非常昂贵。打开Chromium浏览器将花费您50到100兆字节的内存。因此,您应该确保启动的每个浏览器都将关闭。其次,正如已经提到的其他答案一样,您需要手动处置一些对象(例如elementHandle)以清除其资源。

答案 1 :(得分:1)

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();

查看文档: