我正在使用eventsource开发高负载测试工具npm库生成并发sse连接。
我在digitalocean上使用了带有512Mb和1CPU的CentOS。
看看我的代码:
var http = require("http"),
EventSource = require('eventsource'),
openSockets = 0;
http.globalAgent.maxSockets = 70000;
console.log(process.memoryUsage() )
beginTest();
function beginTest (options) {
for (var i = 0; i < 50000; i++) {
setTimeout(formPoster(i),0);
}
}
function formPoster (i) {
var url = "http://remoteserver.com/examples/events/connect.sse",
es = new EventSource(url);
es.onmessage = function(e) {
};
es.onerror = function(e) {
console.log(e);
};
es.onopen = function(e) {
openSockets++;
if (openSockets == 1 ) {
console.log(process.memoryUsage() );
process.exit(code=0);
}
};
}
该代码的问题是巨大的内存泄漏-第一个console.log语句输出
{ rss: 8925184, heapTotal: 5066496, heapUsed: 2113192 }
而第二个(在第一个连接之后)输出这里的{ rss: 373219328, heapTotal: 296538752, heapUsed: 286450700 }
远程服务器与本地机器有大约1500个连接。
什么原因会导致这种内存泄漏?
您没有内存泄漏-您只是同时实例化了许多对象,而垃圾收集事件可能还没有发生。
行setTimeout(formPoster(i),0)
并没有按照您的想法执行——因为您是formPoster
,而不是传递引用,所以超时没有任何作用。您只需立即拨打formPoster
50000次。
事实上,即使您确实向setTimeout
传递了一个函数以进行如下延迟执行:
setTimeout(function() {
formPoster(i)
})
然后,您仍然会看到相同的效果,只是推迟到事件循环的稍后执行。