一、什么是javascript内存泄漏?
内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。
简单理解:无用的内存还在占用,得不到释放和归还,比较严重的时候,无用的内存还会增加,从而导致整个系统卡顿,甚至崩溃
二、常见的内存泄漏
1.意外的全局变量(通常是变量未被定义或者胡乱引用了全局变量)
例如:
这里我们给函数中一个未声明的变量b赋值,这时就会使b成为一个全局变量
function a(){ b=10; } a() console.log(window);
这里的window打印出来就是
这样就会创建一个多余的全局变量,当执行完a函数之后,变量b仍然会存在于全局对象中,这就会造成内存泄漏
解决方法:
我们可以通过使用严格模式“use strict”来避免这一切。在JavaScript文件的开头,它将开启更严格的JavaScript解析模式,从而防止意外的创建全局变量,开启严格模式之后,程序就会报错b没有定义
注意:
需要特别注意那些用于临时存储和处理大量信息的全局变量。如果必须使用全局变量存储数据,就使用全局变量存储数据,但在不再使用时,就手动将其设置为
null,或者在处理完后重新分配。否则的话,请尽可能的使用局部变量。
2.计时器
例如:
setInterval("内存泄漏 ", 1000);
1.setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏
2.启动循环定时器后不清理
var intervalId = setInterval(function () { console.log( '内存泄漏') }, 1000)
它会一直循环下去
解决方法:
使用cLearInterval清理计时器
const intervalId = setInterval(function () { console.log('内存泄漏') }, 1000) clearInterval(intervalId)
3.闭包
例如:
在fn1创建的内部函数fn2是不会回收的,因为它被全局变量f引用, 处于一个随时被调用的状态,所以会造成内存泄漏
function fn1() { var a = 4 function fn2() { console.log(++a) } return fn2 } var f = fn1() f()
解决方法:
在执行完成之后设置为null
function fn1() { var a = 4 function fn2() { console.log(++a) } return fn2 } var f = fn1() f() f = null
4.事件监听未被移除
例如:
function addEvent (){ const node = document.getElementById('warp'); node.addEventListener('touchmove',()=>{ console.log('In Move'); }) } const onTouchEnd = (){ const node = document.getElementById('warp'); node. } useEffect(()=>()=>{ const node = document.getElementById('warp'); node.removeEventListener('touchmove'); }) // 类似react 生命周期函数: componentWillUnmount render(<div id='warp' onTouchEnd={onTouchEnd}> // code... </div>)
5.console.log
因为console.log的对象是不能被垃圾回收的
console.log("123");
6.缓存
建议所有缓存都设置好过期时间,如果缓存过多的话也会造成内存泄漏