js中的垃圾回收机制
垃圾回收机制的主要目的是防止内存泄漏,js有着自己的垃圾回收机制,它用来寻找不在使用的对象并将其占用的内存释放掉
js找寻无用内存的概念是可达性,即那些可以用某些方式访问到的值,这类值被保证存储在内存中
但是像本地函数的局部变量和参数,全局变量,当前嵌套调用链上的其他函数的变量和参数是无法被删除的,
例如声明一个的变量
let a = "sss",
a = null
//此时的sss将被释放,以便a再次的引用声明一个对象
var sss = {
name:"bgc"
}
sss = null
此时的"bgc"变成不可达的状态,没有办法访问也没有办法引用,将"bgc"释放
但是还有一种情况即再声明一个新的变量=sss
var sss = {
name:"bgc";
}
var sss1 = sss
sss = null
此时仍可以通过sss1来访问到"bgc"直到sss1再次被覆盖
当这些变量成为“不可达”的目标是便成为垃圾回收机制将要回收的部分,而js的垃圾回收机制的内部算法有两种
一:“标记-清除”
1.当声明一个新的变量时,垃圾回收机制获取“根”并将其标记
2.之后垃圾回收机制将访问并标记所以来自于它的引用
3.再次标记已标记的引用,直到所有可以被访问的对象都被标记
4.此时将该过程中无法访问的对象进行回收释放占用的内存
二:引用计数
原理为记录声明值的引用次数,每次被引用或赋值给该变量之后将该次数+1,当指向另一个值时将该次数-1,次数为0时将其回收
要注意的时这种方法存在一个问题那就是当对象循环引用时,他们的计数永远不会为0,会导致内存溢出的问题
function Cycle(){
var a = {};
var b = {};
a.prop = b;
b.prop = a;
}
此时a,b的内存永远不会被释放,直到重新赋值null
引用计数的方法不常用
还有一点要注意的是使用闭包时会导致常驻内存,使用闭包不当也会导致内存溢出