为什么我的间隔函数在Node.js中导致内存泄漏?
我有一个正在经历内存泄漏的Node.js
服务器。 它使用socket.io
发送消息给连接的客户端。 我已经设置了一个function,每分钟向客户端发送一次消息。 function是:
var message = "smile"; const doEveryMinute = (socket) => { setTimeout(() => { setInterval(() => doEveryMinute(socket), 6000); socket.emit('smile', message); }, (60 - date.getSeconds()) * 1000); }
这个函数在用户连接的时候被io.on
函数调用:
io.on('connection', function (socket){ doEveryMinute(socket); });
我不明白为什么这会导致内存泄漏,但它肯定是造成一个。 我可以在htop
看到,内存缓慢但肯定填满,直到服务器崩溃显示memory overflow exception
消息。
题:
为什么这段代码会导致内存泄漏?
首先,6000是6秒,而不是60秒。
您永远不会调用clearInterval
,所以使用setInterval
创build的计时器将永远挂起,每6秒钟调用一次。 请记住,这是setInterval
,而不是setTimeout
,所以定时器在第一次触发后不会停止。
本身并不一定是个问题,因为单个定时器的内存使用量可以忽略不计。
但是,由您的计时器调用的函数调用doEveryMinute
,这将创build另一个计时器。 随着每个计时器在6秒后创build另一个计时器,计数将成倍增长。
如果你只想每60秒发送一条消息,你不需要recursion,只需要一个调用emit
定时器:
var message = "smile"; const doEveryMinute = (socket) => { setTimeout(() => { setInterval(() => socket.emit('smile', message), 60000); }, (60 - date.getSeconds()) * 1000); }
请注意,这仍然是不完美的,因为它永远不会停止计时器,当连接下降时,您需要添加一个合适的调用clearInterval
。 60年代以后,我也对setInterval
的可靠性做了一些可疑的假设。 我想知道你的原始代码是否试图处理定时器的不精确性? 这很好,但是如果你想这样做,你需要坚持setTimeout
而不是setInterval
。