JavaScript性能优化 - 常见 GC 算法总结

103 阅读3分钟
  • 引用计数:核心思想就是在内部通过引用计数器来维护每个对象都存在的引用数值,通过这个数值是否为 0 来判读对象是否是一个垃圾对象。从而去回收它的垃圾空间,让垃圾回收器对当前的空间进行回收释放。优点就是即时回收垃圾对象,因为只要数值为 0 就会触发 GC 找到这片空间进行回收和释放。所以也正是由于这样一个特点的存在,引用计数的另外一个优点就是可以最大限度的减少程序的卡顿。因为只要这个空间即将被暂满的时候,垃圾回收器就会进行工作。然后将这个内存去进行释放,让我们的内存空间总是有一些可用的地方;缺点就是无法回收存在循环引用的对象,因为这样的情况意味着当前对象空间的一个引用数字永远是不为 0 的。也就是不能触发当前的一个垃圾回收操作,除此之外它还有一个缺点就是对于资源的消耗是比较大的。因为它这一块有一个引用计数器,然后每次还都要去修改当前这个引用数。而这个对象空间的引用数,有可能会很大也有可能很小。总之频发的操作会有一些资源上的开销,因为我们认为它的速度就不一定那么的快了;
  • 标记清除:这种算法分两个阶段来执行,首先会遍历所有的对象,然后给当前的活动对象进行标记。紧接着就会去把那些没有标记的对象去清除掉,从而去释放掉当前这些垃圾对象所占用的空间。优点就是相对引用计数来讲可以回收循环引用的空间,这一点是引用计数所做不到的;缺点是由于当前算法决定不能够把自己所有的空间去最大化利用,所以很容易就差生碎片化的操作。除此之外,标记清除也不能够去立即回收垃圾对象,也就是说即使在遍历的过程中它发现了这样一个对象是不可达的,但是它也要等到最后才去清除。而且它去清除的时候,当前的程序其实是停止工作的。所以说这也是标记清除的一个缺点;
  • 标记整理:它的做法和标记清除类似,只不过在清除阶段有一些前置的操作。要先去整理一下当前的地址空间,它的优点是可以解决空间碎片化,因为它多处了一个整理地址的操作。缺点和标记清除一样,就是不能即时回收垃圾对象,所以相对于引用计数来说这块也相对是一个缺点。