Node(Meteor)中setTimeout引发内存泄漏问题求助
setTimeout/Meteor.setTimeout 周期性调度内存泄漏问题排查与解决
最近做周期性异步任务调度时踩了个坑,遇到了明显的内存泄漏问题,跟大家分享下我的排查过程和解决结果:
我的需求是每隔15秒执行一个异步函数(该函数返回Promise数组,通过Promise.all处理),要等所有Promise完成、逻辑执行完毕后,再过15秒重新运行。我写的调度逻辑如下:
const schedule = (fn, seconds, runNow = false) => { Meteor.setTimeout(() => { try { Promise.resolve(fn()).then(()=>{ schedule(fn, seconds, false) }).catch((err)=>{ log.error(err) schedule(fn, seconds, false) }) } catch (e) { log.error(e); } }, runNow ? 0 : seconds * 1000); };
一开始我怀疑是Meteor.setTimeout的问题,换成原生setTimeout后,现象完全一致——运行约一小时后内存占用会显著上升,确定是泄漏。更诡异的是,我把业务代码全部注释掉,让被调用的fn只返回空值,泄漏依然存在。我的运行环境是OSX、Node 9.3、Meteor 1.6,查了一圈别人的类似问题,场景都和我不匹配。
问题解决更新
折腾了好久终于找到根源!原来这个schedule函数在另一个未被注意到的任务里被调用了,而那个任务包含大量异步代码,但关键的异步操作没有加await——这就导致任务还没彻底执行完成,schedule就被重复触发了。随着时间推移,未完成的任务实例不断累积,最终引发了内存泄漏。
内容的提问来源于stack exchange,提问作者Abido
相关产品推荐
相关产品推荐

