Node.js 中的活动句柄是什么

What are active handles in Node.js

我发现我的应用程序活动句柄数一直在增加。活动句柄的数量到底是多少?这是我必须注意防止应用程序崩溃的事情吗?

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

查看文档:

活动句柄

句柄是对打开的资源(如打开的文件、数据库连接或请求)的引用。为了理解为什么句柄可能处于活动状态,尽管它们应该被关闭,我给你一个简单的例子:

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 上的服务器,并且 returns 对任何请求发送 Hello World 消息,但发送至 "secret URL" 的请求除外。但是这段代码有问题。当我们 运行 进入 "secret" if 子句时,我们永远不会关闭连接。这意味着客户端将在他想要的时间内保持连接打开。我们应该关闭连接。犯这个错误会增加活动句柄的数量,从而导致内存泄漏。

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

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

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

内存泄漏尤其严重,如果您计划开发一个应该 运行 很长一段时间的脚本,例如 Web 服务器...

如何检查内存泄漏?

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

这跟木偶师有什么关系?

两件事。首先,请求非常便宜。即使您的 Node.js 服务器应用程序存在内存泄漏,您也只会在几千次请求后才开始在内存中看到它。相比之下,木偶师 非常 昂贵。打开 Chromium 浏览器将消耗 50 到 100 兆字节之间的内存。所以你应该确保你启动的每个浏览器都将关闭。其次,正如另一个答案已经提到的那样,您需要手动处理一些对象(如 elementHandle)以清除其资源。