什么是 js 内存泄露?

什么是 js 内存泄露?
最新回答
沵残留的余温ゝ

2021-10-04 02:20:37

JavaScript内存泄露(Memory Leak)是指代码中不再使用的对象或数据持续占用内存,且无法被垃圾回收机制自动释放,导致内存占用不断增加,最终可能引发应用性能下降甚至崩溃。

常见原因及示例
  1. 闭包导致的内存泄露闭包会保留对外部变量的引用,即使外部函数已执行完毕。若闭包未被正确释放,其引用的变量将无法回收。

    function createClosure() { var data = 'Heavy data'; // 占用内存 return function() { console.log(data); }; // 闭包引用data}var closure = createClosure();closure = null; // 仅解除closure的引用,但闭包函数仍存在

    问题:即使closure设为null,返回的闭包函数仍通过作用域链引用data,导致内存无法释放。

  2. 未清除的计时器或事件监听器未清理的定时器或事件监听器会持续占用内存,即使相关功能已不再需要。

    function process() { setInterval(function() { console.log('Processing...'); }, 1000);}process(); // 计时器持续运行,无法回收

    问题:未调用clearInterval清除定时器,回调函数和关联资源会一直存在。

  3. 循环引用对象间相互引用(如DOM元素与JavaScript对象互相引用)会阻止垃圾回收。

    let element = document.getElementById('btn');element.onclick = function() { console.log('Clicked!'); };// 若未解除element的引用,DOM与函数形成循环引用
  4. 全局变量或未清理的缓存全局变量或无限增长的缓存(如数组)会长期占用内存。

    window.globalData = []; // 全局变量function addData() { globalData.push(new Array(1000000).fill('*')); // 内存持续增长}
解决方法
  • 及时释放引用:手动解除不再需要的变量(如closure = null)。
  • 清理定时器和事件:使用clearInterval、removeEventListener等。
  • 避免循环引用:在移除DOM元素前解除事件监听器。
  • 使用弱引用:如WeakMap/WeakSet,允许垃圾回收器回收对象。
  • 性能监控:通过浏览器开发者工具的Memory面板检测内存占用。
预防措施
  • 代码审查:检查闭包、事件监听器和全局变量的使用。
  • 工具检测:使用Chrome DevTools的Heap Snapshot分析内存泄漏。
  • 模块化设计:限制变量作用域,减少意外引用。

总结:内存泄露的核心是无法回收的引用。通过规范代码习惯和定期监控,可有效避免此类问题。