1. 代码中什么是垃圾呢?
不再需要-----就是垃圾
var a = 1 // a 是不是垃圾呢?
...
console.log(a) // a 后面被使用,则不是垃圾
所有的全局变量都不会被垃圾回收
因为任何时候都有可能用到
window
---
|
object
|
Array
|
Promise
...... // 全局自定义变量
变量都有生命周期
function test(){
var b = 2
console.log(b)
} // 变量b只在函数内生效 每次运行函数都会产生一个新的变量b
当我们声明一个对象(或者说复杂数据类型)
单引用:
var a = {
name:'xiaoou'
}
// a 指向一块内存地址 当我把 a = null 时,相当于 a 没指向任何地址空间
// 这块内存就无法被访问到 就会被回收掉
双重引用:
var a = {
name:'xiaoou'
}
var admin = a
a = null
// 这时有两个变量引用此地址 有一个指向null 另一个还是引用着内存地址 则不会被回收
环引用:
function marry(man,woman){
woman.husband = man
man.wife = woman
return {
father:man,
mother:woman
}
}
let family = marry({
name:'john'
},{
name;'Ann'
})
在环引用中,要想回收一个对象,只需要删除所有别人对于他的引用即可
delete family.father
delete family.mother.husband
环引用中切断与外界联系可以直接被垃圾回收
family = null
对象的回收总结:
- 全局对象不会被回收
- 局部中一个对象不被任何变量引用则会被回收
- 环引用中,整体不被引用则环被回收
2. 垃圾的回收算法
标记清除
从全局变量开始,遍历每个全局变量,把引用到的变量标记为被引用,然后依次遍历被标记的变量重复上述步骤,知道最后的变量没有引用其他变量为止,未被标记的变量则会被回收
缺点:变量过多的情况下会比较消耗性能,而且导致JS主线程执行停止
引用计数
- 首先把全局变量记为1
- 其余变量按被引用的次数记数
- 某个变量设置为null时,被引用的变量次数减一
- 直到某个变量的被引用次数为 0 则会被回收掉