我有三个应用程序互相交谈。一个websocket服务器(1)接受来自浏览器的连接,解析url以查看所需的数据,如果它有内存中的数据,则将其提供给客户端,如果不是从另一个名为“fetcher”的应用程序请求它(2)。 Fetcher接收此作业,从返回JSON数据的简单API(3)请求它,并将其发送回websocker服务器,后者将其发布到连接的客户端。然后“Fetcher”开始定期检查该url / job是否有更新,并在发生新数据时将其发送到websocket服务器。
我使用socket.io进行客户端 - websocket服务器通信。 Websocket服务器和提取器通过 ZMQ 套接字进行通话。
我使用 130个连接加载测试websocket服务器。 Websocket服务器每秒向130个客户端发布160KB的数据。一开始,它使用170mb的RAM连接130个,但很快就增加到1GB,尽管没有新的连接。然后socket.io的心跳信号开始失败,导致连接断开。
我使用Nodetime来获取堆快照。在第130个客户端连接之后,这是内存的外观:
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,所以欢迎提出任何意见,谢谢!
答案 0 :(得分:1)
NodeJs可能使用Windows Socket API(包括内存泄漏,旧的已知错误) https://connect.microsoft.com/VisualStudio/feedback/details/605621/winsock-c-program-causes-memory-leak
问题是在关闭网络服务之前永远不会调用WSACleanup。 (混合使用ZMq或Nodejs不会改变这一事实)
现在,随着时间的推移,您将锁定更多内存页面,并且在第一个内存页面已满后,此类通知会增加。
答案 1 :(得分:0)
也许可以尝试添加
var resourceData;
代码中的某处,因为你的内存泄漏可能与全局
有关在此处阅读有关全局变量的更多信息:https://gist.github.com/hallettj/64478