垃圾回收:js具有自动垃圾回收机制,无需手动清除
标记清除
原理:当js函数中声明一个变量的时候,将变量标记为“进入环境”,则变量在内存中占有位置。当变量执行完毕,会将其标记为“离开环境”,js垃圾回收机制检测到“离开环境”,就会自动回收。
在标准浏览器下常用这个回收方式,只是时间间隔不一样
引用计数
原理:js会跟踪每一个变量的引用次数,当变量被声明,并将一个值赋给变量,则引用计数会标注为1,如果变量执行元素或又进行了赋值,则引用计数进行加1,相反,变量赋给其他变量,或者没再进行操作,则次数减1,直到次数变成0,则回收销毁
如果出现循环引用,a调用b,b也调用a,则内存会一直没有释放,容易出现内存泄漏
内存泄漏和内存溢出的区别:
内存泄漏:动态给内存分配空间,在使用完毕之后,没有进行释放,直到程序结束
内存溢出:不顾堆栈分配的数据大小,向内存写入过多的数据,导致数据越界
栈和堆的销毁方式:
栈内存
全局变量:只有浏览器关闭的时候才会回收
局部变量:只有定义在函数里的才是局部变量,函数会产生自己的作用域,当函数执行完毕时,js内存机制会自动进行释放
堆内存
对象或函数在堆内存开辟空间,堆内存就会生成一个引用地址,如果有代码引用了这个地址,则对象不会被销毁。如果想销毁,需要把引用设置成null即可
例如:
var x=new Array()
x=null//销毁了
不被销毁的特殊情况
1.函数执行时,返回了一个对象,并在函数外调用,那么私有变量不会销毁
function fun(){
var x=[1,2,3]
return x
}
var arr=fun()
console.log(arr) 不会被销毁(延长作用域链的一种情况)
2.在一个私有作用域中,给dom元素绑定事件,这个私有作用域不被销毁
var btn=document.getElementById("btn")
btn.οnclick=function(){
var num=11
alert(num)
}
3.闭包(特殊作用域)
闭包是能够有权访问其他函数内部的私有变量的函数,可以理解为函数嵌套函数
必须满足以下特点,缺一不可:
1.函数嵌套函数
2.内部函数访问外部函数的变量
3.变量不会被被垃圾回收
例如:
注意:fun只执行一次,a不被销毁
闭包的作用:
1.可以模拟私有方法
2.用来实现对象的封装
3.用闭包可以访问缓存,当代码执行时间过长,可以先从缓存中读取(提高浏览器的速度)