【问题标题】:Odd Leaking Behavior With Node.JSNode.JS 的奇怪泄漏行为
【发布时间】:2015-04-16 08:37:36
【问题描述】:

获取中等流量的简单服务器(代理)奇怪地泄漏。

代码很简单:

var net     = require('net');
var dgram   = require('dgram');

var server3 = net.createServer();
var udp_sv3 = dgram.createSocket('udp4');

var load_balancer = null;

udp_sv3.bind(9038);
udp_sv3.on('message', udpHandler);
server3.listen(2103);
server3.on('connection', connHandler);

function udpHandler(msg, sender) {
  if (!load_balancer && sender.size === 4) load_balancer = sender;
  if (load_balancer.address === sender.address) {
    this.send(msg, 0, msg.length, 9038, 'xxxxxx');
  } else {
    this.send(msg, 0, msg.length, load_balancer.port, load_balancer.address);
  }
  msg = null;
}

function connHandler(client) {
  var port = this.address().port;
  var gate = net.connect({ host: 'xxxxxx', port: port });

  gate.pipe(client).pipe(gate);

  client.setNoDelay();
  gate.setNoDelay();

  client.on('error', function (error) {});
  gate.on('error', function (error) {});
}

就是这样,但目前正在使用 pm2 进行监控:

│ App name │ id │ mode │ PID   │ status │ restarted │ uptime │       memory │
├──────────┼────┼──────┼───────┼────────┼───────────┼────────┼──────────────┤
│ index    │ 0  │ fork │ 16043 │ online │         0 │ 2h     │ 977.125 MB   │

并且当前连接的套接字数量为267。目前较低,因为通常它会超出1000。但关键是它仍然在泄漏。

怎么了?


  • 发布后 5 分钟 内存位于 987.281MB 并连接了 261 套接字。
  • 3 分钟后:993.676MB260 套接字连接。
  • 10 分钟后:1.060GB248 套接字连接。

节点没有 gc'ing 吗?

【问题讨论】:

  • 当 pm2 报告内存使用情况时,您知道具体测量的是什么吗?在某些平台上可以测量内存信息的一些方法最终包括临时内存分配(用于缓存、代码等),如果需要,系统可以回收这些内存信息,因此不是衡量泄漏的好方法。另外,你在什么平台上运行?换句话说,你 100% 这实际上是一个真正的泄漏吗?如果你运行它几天,它最终会因为内存过度使用而崩溃吗?
  • @jfriend00 我在 ubuntu 上,使用 top 显示相同数量的内存。此外,当我几乎达到最大内存时,应用程序将重新启动。 (可能崩溃了)。
  • 然后,可能是时候做一些堆快照,看看什么在使用所有内存。整理起来不是一件容易的事,但我知道的唯一方法是找出正在使用所有内存的内容。
  • @jfriend00 我使用 memwatch 和其他工具进行了分析,但没有任何问题。

标签: node.js memory-leaks


【解决方案1】:

对于这些行:

client.on('error', function (error) {});
gate.on('error', function (error) {});

您可以尝试 1. 删除它们,因为它们似乎在无目的地分配函数或 2. 在程序的顶级范围内仅定义一次无操作函数并将事件绑定到单个实例(或使用某些东西像来自lodash的_.noop)。这是这里唯一让我怀疑的代码。

【讨论】:

  • 不错,我现在就试试这个。
  • 泄漏仍然存在。改用 golang。
  • 好吧,祝你好运。对于像这样的代理,golang 可能是一个更好的选择。如果您想坚持使用 node,您可能会看到 iojs v1.2 是否更好或 nodejs v0.12。
  • 谢谢。 :) 我使用的是 v0.12,我也尝试过最新的 iojs。我正在使用nvm。两者都有泄漏。现在运行 golang 服务器,750100MB 的在线套接字。这比我的问题上的数字要好得多。
猜你喜欢
  • 2011-09-08
  • 2012-07-06
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 2021-03-28
相关资源
最近更新 更多