为什么我的JavaScript计时器会导致内存泄漏?
我正在开发一个实时数据监控的仪表盘,用setInterval定时更新数据。但发现每次页面切换后内存都没释放,用开发者工具看DOM已经清空了,但内存占用一直涨。代码大致是这样的:
function startMonitoring() {
const dataContainer = document.getElementById('data');
setInterval(() => {
dataContainer.innerHTML = generateRandomData();
}, 1000);
}
我尝试在路由离开时调用了 clearInterval,但发现没生效,因为没保存定时器ID。现在改成保存了ID,但发现dataContainer变量好像还留在内存里。是不是闭包的问题?应该怎么改才能让内存正常释放呢?
就算你后来调用了 clearInterval,但如果你没把 setInterval 返回的 id 存下来,那根本清不掉,等于一直挂着一个每秒执行的回调,DOM 节点还被闭包持有着,自然内存只增不减。
改法很简单,两个关键点:
第一,必须保存 timerId,方便后续清理
第二,在组件卸载或页面切换时,主动清除定时器,并解引用 DOM 元素
代码可以改成这样:
你在路由切换或者组件销毁的时候,记得调一下 stopMonitoring。这样定时器清了,闭包里的 dataContainer 也没了强引用,V8 就能正常回收内存。
另外提醒一句,这种实时监控最好加个失败重试和节流,别让 API 调用崩了还一直 retry,那就又是另一个内存问题了。