Skip to main content

内存泄漏

概述

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

常见泄漏点

闭包

闭包的概念是我有个代码区域,使用了外层区域某个变量,那么这个代码区域执行完之前,外层的那个变量肯定不能被释放,这就是闭包。

定时器

使用setInterval和setTimeout没有清除,导致定时器的回调函数以及内部依赖的变量没有被回收

this.timer = setInterval(()=>{
console.log('i am still alive!')
}, 500)

解决方式:

当不使用的interval和timeout使用clearInterval或clearTimeout

千万注意this.timer = null并不能清理掉定时器!定时器这玩意儿还在,只是你找不到它了! 一定要写clearInterval(this.timer)才能清理掉!

动画

现代浏览器的requestAnimationFrame也要手动清除,有一个cancelAnimationFrame方法

未捕获的异常/console.error

console打印错误对象,可以将大量数据保存在内存中,传递给console.log的对象不能被内存回收,所以要去除console

DOM泄漏

  • 给dom对象添加的属性是一个对象

var a = {};
document.getElementById('id').diyProp = a;

解决方法:在window.onload中加上document.getElementById('id').diyProp = null;

  • 元素引用没有清理

var a = document.getElementById('id');
document.body.removeChild(a);
// 不能回收,因为存在变量a对它的引用。虽然我们用removeChild移除了,但是还在对象里保存着#的引用,即DOM元素还在内存里面。

解决方法:a=null

jQuery

jQuery时代,有好多对DOM的引用this.testDom = $('#test')就拿到DOM了,这个跟闭包搅合在一起比较占用内存,ES6有个语法叫weakMap,就是为了解决DOM引用占内存的问题

事件的绑定没有移除

解决方法:移除事件监听

链接

优秀文章