利用github上ws 包 https://github.com/websockets/ws 实现的服务端,在并发测试时候,写了一些脚本做测试。 3万client端连接尚服务端,然后断开。在gc 回收稳定之后,内存较初始要高。且连接数越多,内存占用会越多。 github上提出的问题。 https://github.com/websockets/ws/issues/804
不知道这种情况是否正常?为什么会有这种内存占用的情况呢?
我WIN10 NODEJS 6.9.4 最多200M内存,断开所有连接一直都是停留在190M,然后新建立一个连接上来,就降到了50M左右,断开连接,过几分钟就变成了25M
用内存泄露工具跑了下,没有发现有什么无法回收的引用泄露
图一是保持10K连接的内存,最大内存开销是Object,个数有3万多个,内存对象定位是ws.clients,这个是用来保存在线连接的一个数组.看引力图也没有发现非常长的对象引用.应该不会导致内存泄露.
图二是断开所有客户端连接以后,Object对象也减少到了1000左右,内存占用也从70多M,降到了7M.
@sunwukong2012 请问这个是什么工具监控node内存的,不胜感激
@sunwukong2012 被拿来用了哇…好开心
请问你用那个脚本进行测试。@sunwukong2012
如果回调函数不进行回调,不知道会否出现问题呢? 比如
clientsMap.hasWsConnect(userId, function() {
/*保存APP与Websocket长连接到clients集合当中*/
clientsMap.addGallery(userId, ws);
});
exportrs.hasWsConnect(userId,fun){
if(clients.has(userId){
fun(); //执行回调
}else{
//不执行回调
}
}
不知道这样会否出现问题? @sunwukong2012 @hyj1991
@bingino
@kimown
用的easy-monitor,来监控的.
挺好用的.
工具的原文在这里:
https://cnodejs.org/topic/58d0dd8b17f61387400b7de5
不进行回调应该不会导致内存泄露.
我觉得是你的clients集合当中的问题
如果你再用户断线以后,没有及时把断线用户清除出clients集合,那么这个断线的用户的ws对象就会一直被clients集合引用,这样肯定不会被GC回收掉.
重复的这样以后就会内存泄露了.
你先用这个工具跑一下,看看是哪些对象一直被引用,从而导致释放不掉.
@hyj1991 谢谢开发那么方便的工具,非常直观也简单,这个比v8-profiler好用多了,用浏览器打开,数据量非常大,打开的时候经常卡个半天,查找起来也确实麻烦.还不能线上观察.
你误会啦,我指的是你用来测试的服务端和客户端脚本是哪个,而不是工具?因为你测试的结果和我测试结果出入较大,能否提出你测试的脚本?
@bingino 我复制的你在github上回复的代码测试的,不过我一个脚本也就只能跑10K连接,多了就报错,socket hang up.
不过可以开2个进程来跑20K,测试结果也差不多.
client.js
var WebSocket = require(‘ws’);
function cerateclient(){ var ws = new WebSocket(“ws://localhost:8001/”); ws.onopen = function() { ws.send(‘connnect’); };
ws.onmessage = function(evt) { //console.log(evt.data); }; }
for(var i =0 ; i < 10000; i++){ cerateclient(); }
server.js
const easyMonitor = require(‘easy-monitor’); easyMonitor(‘test’);
const WebSocket = require(‘ws’);
const wss = new WebSocket.Server({ host:‘127.0.0.1’, perMessageDeflate: false, port:8001 });
wss.on(‘connection’, function connection(ws) { ws.on(‘message’, function incoming(message) { //console.log(‘received: %s’, message); }); ws.send(‘something’); });
v8的垃圾回收是惰性的,你可以打上 --expose-gc
然后在代码里用global.gc()
试试
@Equim-chan 是的,内存会一直占用,等你需要用到更大内存时候就开始回收,和linux内存管理差不多.
好的,谢谢两位。@Equim-chan @sunwukong2012
咨询一下,我在使用easy-monitor。按照教程所讲。安装并引入了包。使用node命令启动程序时候,报出夜莺成功连接127.0.0.1:26666 success 1495795000(1).png 但我在谷歌浏览器打开连接 http://127.0.0.1:12333 时候,提示拒绝连接请求。这是我的projectname 处出现问题了么? /path/projectA/bin/main.js 以这路径为例,我的project name直接写projectA这样可以么? @sunwukong2012 @hyj1991