【问题标题】:What are active handles in Node.jsNode.js 中的活动句柄是什么
【发布时间】:2018-07-19 09:37:12
【问题描述】:

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

【问题讨论】:

  • 表示打开文件或数据库连接。如果您看到这种情况无限增长,那肯定是要解决的问题。
  • 我正在使用一个名为 puppeteer 的模块,它是一个无头浏览器控制器,每次打开和关闭页面时,pm2 监视器上的这个值都会不断增加。有关如何防止/调试此问题的任何指示?
  • @Balanarayanan 我在 NightmareJS 上遇到了同样的问题,并通过调用 .end() 解决了它(这会杀死 Electron 子进程并关闭连接)。我猜 puppeteer 的等价物是调用 browser.close()。

标签: node.js pm2 puppeteer


【解决方案1】:

活动句柄

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

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 服务器应用程序中存在内存泄漏,您也只会在几千个请求后才开始在内存中看到它。与此相反,puppeteer 非常昂贵。打开 Chromium 浏览器会消耗 50 到 100 兆字节的内存。因此,您应该确保您启动的每个浏览器都将关闭。其次,正如已经提到的另一个答案,您需要手动处置一些对象(如elementHandle)以清除它们的资源。

【讨论】:

    【解决方案2】:

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

    查看文档:

    【讨论】:

    • 这根本不能回答所提出的问题
    • “这是我必须采取的措施,以防止应用程序崩溃吗?”被问到:释放句柄是防止内存泄漏的好方法,从而防止您的应用随机崩溃。
    • 我不会对此投反对票,因为我认为这些信息对使用 puppeteer 的人很有用,但原始问题对 puppeteer 的引用仅在 cmets 和标签中。如果回答了一般问题,“活动句柄的数量到底是多少”和“这是我必须处理的事情......”,那就太好了。后者是一个是或否的问题,答案真的取决于你在做什么。我想说这不能回答问题对我没有帮助。我应该问的是,“有人可以更笼统地回答这个问题吗”。
    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多