# 内存泄漏与避免
内存泄漏(Memory Leak)顾名思义.就是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果的现象。
关于内存泄漏:
即使是1byte的内存,也叫内存泄漏,并不一定是导致浏览器崩溃、卡顿才能叫做内存泄漏。 一般是堆区内存泄漏,栈区不会泄漏。
基本类型的值存在内存中,被保存在栈内存中,引用类型的值是对象,保存在堆内存中。所以对象、数组之类的,才会发生内存泄漏。
# 内存泄漏的情形
下面我们来看看,有哪些方面的内存泄漏:
# 1. 闭包
闭包可以维持函数内部变量驻留内存,使其得不到释放.
function onclick(){
let obj=document.getElementById("button");
obj.onclick=function(){
//.
}
}
1
2
3
4
5
6
2
3
4
5
6
上例,函数内部定义了一个变量,这个变量的事件引用了内部函数,并且这个事件回调函数的引用外暴了,形成闭包.
# 2. 意外的全局变量引起的内存泄漏
function(){
menu='navite';//menu为一个全局变量,全局变量常驻内存
}
1
2
3
2
3
# 3. 没有清理的dom元素的引用
dom元素不存在,该引用还存在。
# 4. 定时器没有被及时的被销毁
var conentByName=getConentByName();
setInterval(function(){
let content=document.getElemetById('key_id');
if(content){
content.text = conentByName;
}
},1000);
1
2
3
4
5
6
7
2
3
4
5
6
7
# 5. 监听事件造成的泄漏
# 内存泄漏的避免
- 谨慎使用闭包 a、在业务不需要用到的内部函数,可以重构在函数外,实现解除闭包.
b、闭包内,局部变量使用后或不再需要,及时的清除掉
- 减少不必要的全局变量,如果用了,最好在声明周期钩子中或再函数调用之前,及时的清除掉.
- 减少生命周期较长的对象,及时对无用的数据进行释放销毁.
- 避免创建过多的对象,对不用的对象及时的释放.
- 对注册的事件,再不用的时候,及时的解耦.释放资源.
记住一个原则:不用的东西,及时归还,毕竟你是'借的'嘛。
1. 减少不必要的全局变量,使用严格模式避免意外创建全局变量。
2. 在你使用完数据后,及时解除引用(闭包中的变量,dom引用,定时器清除)。
3. 组织好你的逻辑,避免死循环等造成浏览器卡顿,崩溃的问题。
1
2
3
4
5
2
3
4
5