内存泄漏是指:一块被分配的内存既不能使用又不能回收,直到浏览器进程结束;
以下列举内存泄漏的情况:
<body>
<div class="main">
<div class="test">天</div>
<div class="item">天</div>
<div class="item">向</div>
<button id="add">点击我增加</button>
<button id="remove">点击我减少</button>
<script>
/* 1.意外的全局变量
js对未声明变量会在全局最高对象上创建它的引用,(是以属性存在的,而不是变量),
如果在浏览器上就是window对象,如果在node环境下就是global;
如果未声明的变量缓存大量的数据,它可能只有在页面被刷新或者被关闭的时候才会释放内存,这样就造成了内存意外泄漏
解决方案: 针对上面类型的内存泄漏我们在平时一定要声明变量,不要有全局直接引用。
(在JavaScript文件中添加 “use strict”,开启严格模式,可以有效地避免上述问题。) */
function my() {
name = "my name is tom";
my();
}
console.log(window);
运行结果:
/* 2.console.log
作为前端平时使用console.log在控制台打出相对应的信息可以说是非常常见。
但如果没有去掉console.log可能会存在内存泄漏。
因为在代码运行之后需要在开发工具能查看对象信息,所以传递给console.log的对象是不能被垃圾回收 */
/* 3、闭包
首先闭包是一个函数A返回一个内联的函数B,即使A函数执行完函数B也可以访问函数A里面的变量,这就是一个简单的闭包。
本质上闭包是将函数内部和外部连接起来的一座桥梁。
在my2()内部创建的sendName()函数是不会被回收的,因为它被全局变量test引用,处于随时被调用的状态。
如果向释放内存可以设置test=null;由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。
过度使用闭包可能会导致内存占用过多 */
function my2(name){
function sendName() {
console.log(name)
}
return sendName
}
var test= my2("mary")
test()
/* 4、DOM泄漏
浏览器中DOM和js采用的是不一样的引擎, DOM采用的是渲染引擎,而js采用的是v8引擎,所以在用js操作DOM时会比较耗费性能,因为他们需要桥来连接他们。
为了减少DOM的操作,我们一般将常用的DOM,我们会采用变量引用的方式会将其缓存在当前环境。
如果在进行一些删除、更新操作之后,可能会忘记释放已经缓存的DOM,话不多说直接来个例子
在我点击了三次增加之后,可以明显的看到节点(绿线)有三次明显的增加,之后我又删除了一个节点,但绿线没有下降,这是为什么呢?,这也就是内存泄漏。
原因就是删除的DOM在js中有全局的引用。也就是我删除的test在文中被引用,所以无法释放内存。所以在删除更新等操作后应该将其设置为null
*/
var add =document.querySelector("#add");
var remove=document.querySelector("#remove");
var main=document.querySelector(".main")
var test=document.querySelector(".test")
add.onclick=function () {
var itemN =document.createElement('div')
var txt =document.createTextNode('上')
itemN.appendChild(txt);
main.appendChild(itemN);
}
remove.onclick=function (){
main. removeChild(test)
}
运行结果:
/* 5、被遗忘的timers(定时器)
js中常用的定时器setInterval(),setTimeout().他们都是规定延迟一定的时间执行某个代码,
而其中setInterval()和链式setTimeout()在使用完之后如果没有手动关闭,会一直存在执行占用内存,
所以在不用的时候我们可以通过clearInterval()、clearTimeout()来关闭其对应的定时器,释放内存。 */
</script>
</body>