这是大佬总结的:
https://segmentfault.com/a/1190000018605776
https://javascript.info/garbage-collection
下面是我自己总结的(都是通俗易懂的话):
JS的垃圾回收是为了清除掉那些我们用不了的变量所占的内存,所谓用不了,用专业一点来的话说就是不可达,比如说:
let a = {
name: 'xiaoming'
}
let b = {
friend: a
}
a = null; //a的值是一个空指针对象
delete b.friend; //b就只剩{}了
以上代码一顿疯狂操作后,对象{name:'xiaoming'}
就再也无法被访问到了,也就是说它是不可达的。那么垃圾收集器下次运行时就会将它所占的内存给回收了。什么是垃圾收集器呢?这是JS自带的一个功能,也就是说JS具有自动垃圾收集机制。
那么怎么才能知道变量不可达呢?最常用的一种方式就是标记清除方式:
垃圾收集器在运行的时候会给存储在内存中所有变量都加上标记(怎么标记就不用深究了),然后它会去掉环境中的变量和被环境中的变量引用的变量的标记(环境就是指执行环境,除了全局执行环境外,每个函数都有自己的执行环境,执行流进入一个函数时,函数的执行环境就会被压入执行栈中),那么这些被去掉标记的,就是不会被清除内存的变量(因为执行环境还在用),那些身上还有标记的,在下次垃圾收集器运行时,就会被清除掉内存了。
函数执行完,被执行栈弹出后,函数内的局部变量会被自动解除引用
上面说到,执行环境中的变量(函数内部就是局部变量)和它们引用的其它变量是会被取消标记的,就代表不会被回收,但是函数都执行完了,执行环境也不在这里了,留着局部变量也没啥用了,那就回收了吧,所以局部变量会在它们离开执行环境时自动被解除引用。当然了,全局环境中,你也可以手动解除引用(给变量null),让值脱离执行环境,以便垃圾收集器下次运行时将其回收。