我认为在将x个 EventSource 客户端连接到它时,我遇到了使用 Express 应用程序的内存泄漏。连接客户端并发送x消息并断开连接后,我的 Express 应用程序仅释放少量已分配的堆/ RSS。
为了确认这一点,我在启动服务器时保存了 Heapdump ,在将7,000个客户端连接到服务器并向每个客户端发送x消息之后保存了一个。在等待堆快照之前,我等待了一段时间让GC有机会清理。
为了比较这些堆快照,我将它们加载到Chrome开发者工具配置文件视图中,然后选择"比较"模式。
我的问题是:
1)如何解读这些数字? (有关参考,请参阅附加的堆快照截图。)
2)例如,看起来 Socket 对象几乎不释放任何对象,这是正确的吗?
3)您能否给我更多提示来调查此问题?
答案 0 :(得分:1)
关于我的评论......
Javascript无法清理一段内存,如果有什么东西指向它大约2年前有人发现了一个漏洞,它很快被关闭了,就像这样工作
var someData = ["THIS IS SOME DATA SAY IT WAS THE SIZE OF A SMALL APPLICATION"];
var somePointer = someData[0];
delete someData;
然后,他们将应用程序注入somePointer,因为它是现在没有数据时对内存位置的引用。嘿presto你注入记忆。
因此,如果存在上述somePointer = someData[0];
之类的引用,那么在您delete someData
之前无法释放内存,因此您必须删除所有对您想要清理的内容的引用ALL_CLIENTS.push(this);
64正在通过ALL_CLIENTS访问您的系统内存,所以您可以做的是
第157行
_.each(ALL_CLIENTS, function(client, i) {
var u; // holds a undefined value (null, empty, nothing)
client.close();
//delete ALL_CLIENTS[i];
ALL_CLIENTS[i] = u;
ALL_CLIENTS.unused++;
});
另一方面,这不是内存泄漏内存泄漏说你有这个服务器你关闭它如果内存没有释放你退出后然后你有内存泄漏,如果它确实清理它背后的内存它不是泄漏它只是糟糕的内存管理
感谢@Magus指出删除不是你可以使用的最好的东西但是我永远不会建议你实现限制结构,但你可以尝试
第27行:ALL_CLIENTS.unused = 0;
第64行:
var u;
if(ALL_CLIENTS.unused > 0){
for(var i = 0; i < ALL_CLIENTS.length; i++){
if(ALL_CLIENTS[i] == u){
ALL_CLIENTS[i] = this;
ALL_CLIENTS.unused--;
i = ALL_CLIENTS.length;
}
}
}else{
ALL_CLIENTS.push(this);
}
答案 1 :(得分:1)
你可以免于内存泄漏,并作为奖励避免垃圾收集器。 你所要做的只是对象轮询。
您可以执行类似
的操作var clientsPool = new Array(1000);
var clientsConnected = [];
当新客户端连接时,您可以
var newClient = clientsPool.pop();
//set your props here
clientsConnected.push(newClient);
这是避免垃圾收集器并防止内存泄漏的一种很棒的方法。当然,还有更多的工作要做,你必须仔细管理它,但它的性能非常值得。
有一个很棒的谈论它,你走了 https://www.youtube.com/watch?v=RWmzxyMf2cE