JS内存泄露

JavaScript05

JS内存泄露,第1张

当内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。Chrome限制了浏览器所能使用的内存极限,64位为1.4GB,32位为1.0GB。

1.意外的全局变量

.未声明变量

.使用this创建的变量(this指向window)

解决办法:

.避免创建全局变量

.使用严格模式,在js文件头部或者函数的顶部加上use strict

2.闭包引起的内存泄露

原因:闭包可以读取函数内部的变量,然后让这些变量是始终保存在内存中。如果在使用结束后没有将局部变量清除,就可能导致内存泄露。

解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中。

3.没有清除的DOM元素引用

原因:虽然别的地方删除了,但是对象中还存在对DOM的引用。

解决办法:手动删除,赋值为null

4.被遗忘的定时器或者回调

解决办法:手动删除定时器和DOM,removeEventListener移除事件监听

内存溢出是一种程序运行会出现的错误,当程序所需要的内存大于剩余内存(机器能提供给你的内存),就会抛出内存溢出的错误var obj = {}for (var i = 0i <100000000i++) {obj[i] = new Array[100000000]}登录后复制内存泄漏占用的内存没有及时的释放从而失去控制,从而造成内存的浪费。内存泄漏多了就容易引发内存溢出。常见的内存泄漏案例:1、意外的全局变量function fn() {var name = '张三'var age = 18address = '上海'// 没有用var定义,这时候address是全局的}fn()// 因为address会被变量提升到了全局变量,fn调用完成后address还保留在内存中登录后复制2、没有及时清除定时器// 没有及时清理定时器var timer = setInterval(() =>{console.log(new Date())}, 1000)// clearInterval(timer) 及时清理定时器登录后复制3、没有及时清理闭包// 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长,容易造成内存泄露function fun() {var a = 5function getA() {return a}return getA}var f = fun()f() // 5// f = null 让内部函数成为垃圾对象,释放闭包登录后复制4、没有及时清理清理dom元素的引用var dom = document.getElementById('box')document.body.removeChild(dom) // dom删除后,下面依然能打印出整个divconsole.log(dom)// <div id="box">嘿嘿嘿</div>dom = nullconsole.log(dom)// 释放资源,解除引用登录后复制5、addEventListener监听事件的解除,监听的时候addEventListener,在不监听的时候要使用removeEventListener。

1、当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。

2、对于纯粹的 ECMAScript 对象而言,只要没有其他对象引用对象 a、b,也就是说它们只是相互之间的引用,那么仍然会被垃圾收集系统识别并处理。但是,在 Internet Explorer 中,如果循环引用中的任何对象是 DOM 节点或者 ActiveX 对象,垃圾收集系统则不会发现它们之间的循环关系与系统中的其他对象是隔离的并释放它们。最终它们将被保留在内存中,直到浏览器关闭。

3、闭包可以维持函数内局部变量,使其得不到释放。

4、

a = {p: {x: 1}}

b = a.pdelete a.p

执行这段代码之后b.x的值依然是1.由于已经删除的属性引用依然存在,因此在JavaScript的某些实现中,可能因为这种不严谨的代码而造成内存泄露。所以在销毁对象的时候,要遍历属性中属性,依次删除。

5、一些DOM操作:IE系列的特有问题 简单的来说就是在向不在DOM树上的DOM元素appendChild;IE7中,貌似为了改善内存泄露,IE7采用了极端的解决方案:离开页面时回收所有DOM树上的元素,其它一概不管。