JS垃圾回收算法

182 阅读2分钟

引用计数算法

核心思想:

  • 通过维护一个引用数值来回收垃圾对象

优点:

  • 发现垃圾时立即回收
  • 最大限度减少程序暂停

缺点:

  • 无法回收循环引用的对象
  • 时间开销大
  • 资源消耗大

循环引用示例:

    function fn() {
        const obj1 = {}
        const obj2 = {}
        
        obj1.name = obj2
        obj2.name = obj1
        
        return 'lg is a coder'
    }
    
    fn()

当fn函数执行完成之后,正常来说obj1和obj2应该被回收,但是这里因为obj2被obj1.name引用,obj1被obj2.name引用,所以造成了无法回收的问题。

标记清除算法

核心思想:分标记和清除两个阶段完成

  • 第一阶段: 遍历所有可达对象并标记
  • 第二阶段:遍历所有对象清除没有标记的对象,同时清除之前所做的标记,并把回收的空间放到空闲链表上

优点:

  • 解决引用计数算法无法解决的循环引用的回收操作

缺点:

  • 产生空间碎片化,产生浪费。由于当前所回收的空间在地址上的不连续造成的
  • 不会立即回收垃圾对象

image.png 图中所示,两边的空间是回收得到的空间,被中间正在使用的空间隔开,如果后续需要申请的内存空间大小刚好为两边空间之和,那就没办法直接使用这两边的空间。

标记整理算法

核心思想:

  • 标记整理可以看做是标记清除的增强
  • 标记阶段的操作和标记清除一致
  • 清除阶段会先执行整理,移动活动对象位置

image.png

image.png

移动活动对象的位置,然后将非活动对象进行回收。

优点:

  • 减少空间碎片化

缺点:

  • 不会立即回收垃圾对象