为什么我的间隔函数在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