Node.js使用setInterval时内存占用增长问题排查求助
Node.js内存占用异常排查记录
问题概述
遇到Node.js内存占用异常问题,不确定是否与垃圾回收(GC)相关。
监控数据与周期规律
过去6小时的监控数据显示,内存占用的增长与下降模式每小时几乎完全一致,该规律在过去1天甚至3天的监控中同样存在:

周期观察到的固定规律:
- 内存释放的最低点始终出现在每小时的42分
- 随后内存持续增长,在每小时05分时出现第二次内存释放
- 之后内存继续增长至每小时40分达到峰值,随后回到循环起点
应用基本情况
- 提供若干CRUD API,同时处理反向代理请求
- 包含几个基于
setInterval实现的定时任务,每60秒调用第三方API拉取数据 - 检查所有.js文件后未发现用于存储增量数据的全局变量,仅存在应用启动时加载的配置数据
- 定时任务不会更新全局变量,仅在
setInterval作用域内临时存储数据,任务结束后将数据推送至数据库(未主动清理该作用域内的变量,预期GC会自动回收)
查阅资料了解到GC通常在数毫秒内运行,不应延迟一小时才回收未使用对象,因此寻求解决办法。
排查过程
尝试替换setInterval调用方式
找到描述类似症状的内存泄漏相关内容后,改用递归调用结合clearInterval的方式实现定时任务:
function b() { var a = setInterval(function() { console.log("Hello"); clearInterval(a); b(); }, 50); } b();
经过6小时监控,该方案无效,内存变化规律仍无改变。
延长定时任务间隔时间
将setInterval的间隔时间从60秒延长至120秒,监控发现内存占用变得更稳定,但仍无法解释内存突然释放而非持续耗尽的现象:
长期稳定性验证
经过24小时观察,延长间隔时间后的应用运行稳定:
结论
垃圾回收的原则之一是通常在JavaScript引擎空闲、低活动时段触发,以最小化对应用性能的影响。延长setTimeout或setInterval的间隔时间,能让JS引擎有足够的“喘息”时间正常触发GC,从而解决内存异常波动问题。
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

