node.js - 使用 Socket.IO + Node.js + ZMQ 发送消息时发生内存泄漏

标签 node.js sockets memory-leaks socket.io zeromq

我有三个应用程序相互通信。 websocket 服务器 (1) 接受来自浏览器的连接,解析 url 以查看需要哪些数据,如果内存中有数据,则将其提供给客户端,如果没有,则从另一个名为“fetcher”的应用程序 (2) 请求它。 Fetcher 接收此作业,从返回 JSON 数据的简单 API (3) 请求它,并将其发送回 websocker 服务器,该服务器将其发布到连接的客户端。 “Fetcher”然后开始定期检查该 url/job 是否有更新,并在新数据发生时将其发送到 websocket 服务器。

我使用 socket.io 进行客户端-websocket 服务器通信。 Websocket 服务器和 fetcher 通过 ZMQ 套接字进行对话。

我用 130 个连接 加载测试 websocket 服务器。 Websocket 服务器每秒向 130 个客户端发布 160KB 的数据。一开始,它使用 170mb 的 RAM 来进行 130 个连接,但很快增加到 1GB,尽管没有新的连接。然后socket.io的心跳信号开始失效,导致连接断开。

我使用 Nodetime 拍摄堆快照。在第 130 个客户端连接后,内存如下所示:

enter image description here

346 个缓冲区对象,总共 44MB

在四分钟内,Buffer 对象的数量急剧增加(同样,没有新连接):共有 3012 个,总内存为 486MB。再过 10 分钟,有 3535 个,总内存消耗为 573MB

我用Mozilla的memwatch查找了哪一行添加到内存中,发现是这个函数:

function notifyObservers(resourceId) {
  var data = resourceData[resourceId];
  io.sockets.in(resourceId).emit('data', data);
}

如果我将这些行注释掉,内存使用量将保持不变,因此这是另一个确认。

任何想法如何发生?我在 ZMQ 的订阅者套接字方法中调用此函数,我怀疑它与此有关。如果我删除函数并将它们合并为一个,这是生成的代码:

// Receive new resource data
const resourceUpdatedSubscriber = zmq.socket('sub').connect('tcp://localhost:5433');
resourceUpdatedSubscriber.subscribe('');

resourceUpdatedSubscriber.on('message', function (data) {
  var resource = JSON.parse(data);

  resourceData[resource.id] = resource.data;

  io.sockets.in(resourceId).emit('data', resourceData[resource.id]);
});

我的所有代码(包括负载测试)都是公开的,您可以在此处找到此 Web 套接字服务器:https://github.com/denizozger/node-socketio/blob/master/server.js见第 138 行。

两个月前我开始学习 Javascript 和 Node.js,欢迎大家提出意见,提前致谢!

最佳答案

NodeJs 可能使用 Windows Socket API(其中包括内存泄漏,旧的已知错误) https://connect.microsoft.com/VisualStudio/feedback/details/605621/winsock-c-program-causes-memory-leak

问题是在您关闭网络服务之前永远不会调用 WSACleanup。 (混合 ZMq 或 Nodejs 不会改变这一事实)

现在,随着时间的推移,您将锁定更多的内存页,并且在第一个内存页满后这种通知会增加。

关于node.js - 使用 Socket.IO + Node.js + ZMQ 发送消息时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20566673/

相关文章:

objective-c - 泄露报告看似不相关的问题

opencv - 如何停止for循环(OpenCV)

node.js - Alexa Skill 中的 https 请求

java - ServerSocketChannel 已关闭,但 TCP ESTABLISHED 仍在

node.js - NodeJS 记录器 : winston. transports.DailyRotateFile 不是函数

java - socket -V- 休息性能

c - gethostbyname 在 Fedora 32 位上工作正常,但在 64 位上失败

ios - 具有大量数据 Swift 的 CollectionView

node.js - 我在哪里为node.js设置rejectUnauthorized = false

node.js - 错误 : Could not get input duration, 请指定固定时间标记