js的垃圾回收机制

什么是js垃圾回收机制 ? 

js的垃圾回收机制就是定时回收闲置资源的一种机制 , 每隔一段时间, 执行环境都会清理内存中一些没用的变量释放它所占用的内存 .

核心思想 : 找到没用的变量, 释放它们的内存

两种主要的回收策略

  1. 标记清除
  2. 引用计数

1. 标记清除

标记清除是现在最常使用的垃圾回收策略, 使用标记清除作为垃圾回收机制的浏览器会在垃圾回收程序进行时会做如下几步 : 

  • 标记内存中所有的变量
  • 把在上下文(全局作用域, 脚本作用域)中声明的变量,以及在全局被引用的变量的标记删除掉, 剩下的所有带标记的变量就被视为要删除的变量, 垃圾回收执行时释放它们占用的内存
  • 内存清理, 清除垃圾

伪代码简单说明一下 : 

    // 变量 color,dog 在全局环境下声明, 不会被清除
    const color = 'red';
    var dog = '金毛';
    {
      let cat = 'kitty'; // 变量 cat 在块作用域中声明, 且没有被全局所引用, 所以会在下一次垃圾 
                            回收执行时, 释放其内存
    }

2. 引用计数

引用计数是一种不常用的垃圾回收策略, 主要核心思路就是记录值被引用的次数, 一个值被赋给变量,引用次数+1, 这个变量在某个时刻重新赋了一个新值, 旧值的引用次数-1变为了0, 在下次垃圾回收程序进行时就会释放它的内存

引用计数存在的问题 : 循环引用

伪代码简单实例 : 

    function fn() {
      const obj1 = new Object() // new Object 在堆内存中创建了一个对象1 {} 这个值被赋值给obj1 于是引用次数 + 1
      const obj2 = new Object() // new Object 在堆内存中创建了一个对象2 {} 这个值被赋值给obj2 于是引用次数 + 1

      obj1.a = obj2; // obj2 被赋值给 obj1的a属性  于是对象1的引用次数 1+1 = 2
      obj2.a = obj1; // obj1 被赋值给 obj2的a属性  于是对象2的引用次数 1+1 = 2
    }
    // 此时两个对象之间相互引用 且如果函数多次调用, 又会重新执行多次函数体, 又会多了n个相互引用的对象占用内存

为了避免循环引用的问题 : 我们可以手动将其设置为null

      obj1.a = null; 
      obj2.a = null; 
 //   通过设置为null 可以切断两者之间的引用, 在下次回收时就会清理释放掉

书写代码时的注意点 : 

闭包变量被外部引用时, 会造成内存泄漏, 在不使用时将其设置为null, 释放内存空间. 

上一篇:javascript 深拷贝的问题


下一篇:神奇的Object.assign()