浅谈 JS 垃圾回收机制

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'
})
环引用.png

在环引用中,要想回收一个对象,只需要删除所有别人对于他的引用即可

delete family.father
delete family.mother.husband
循环引用删除.png

环引用中切断与外界联系可以直接被垃圾回收

family = null
删除外界环引用.png
对象的回收总结:
  1. 全局对象不会被回收
  2. 局部中一个对象不被任何变量引用则会被回收
  3. 环引用中,整体不被引用则环被回收

2. 垃圾的回收算法

标记清除

从全局变量开始,遍历每个全局变量,把引用到的变量标记为被引用,然后依次遍历被标记的变量重复上述步骤,知道最后的变量没有引用其他变量为止,未被标记的变量则会被回收

垃圾回收之标清除.png

缺点:变量过多的情况下会比较消耗性能,而且导致JS主线程执行停止

引用计数
  1. 首先把全局变量记为1
  2. 其余变量按被引用的次数记数
  3. 某个变量设置为null时,被引用的变量次数减一
  4. 直到某个变量的被引用次数为 0 则会被回收掉
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容