MST

星途 面试题库

面试题:JavaScript中常见的垃圾回收算法有哪些及其原理

请简述JavaScript中至少两种常见的垃圾回收算法,并说明它们是如何判断哪些内存可以被回收的,以及在实际应用场景中的优缺点。
40.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

标记清除算法(Mark - Sweep)

  1. 判断内存可回收方式
    • 当变量进入执行环境(例如函数被调用)时,会被标记为“进入环境”,离开执行环境时标记为“离开环境”。垃圾回收器在运行时,会给存储在内存中的所有变量都加上标记。
    • 然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。
    • 在此之后,所有仍然带有标记的变量就是待删除的变量,因为环境中的变量已经无法访问到这些变量了,垃圾回收器会将这些变量占用的内存空间回收。
  2. 优点
    • 实现相对简单,主流浏览器都支持这种算法,兼容性较好。
    • 可以处理循环引用的情况,只要从根对象(全局对象等)出发无法访问到的对象,即使存在对象间的循环引用,也会被回收。
  3. 缺点
    • 会产生内存碎片,在频繁的分配和回收后,可能导致大对象无法找到连续的内存空间进行分配。
    • 标记和清除的过程是停止应用程序执行的(Stop - the - World),可能会造成应用程序的卡顿,尤其是在内存较大、对象较多的情况下。

引用计数算法(Reference Counting)

  1. 判断内存可回收方式
    • 跟踪记录每个值被引用的次数。当一个值被创建并赋值给一个变量时,这个值的引用次数为1。如果同一个值又被赋给另一个变量,那么引用次数加1。当包含这个值的变量被其他值覆盖或者离开作用域时,引用次数减1。当一个值的引用次数变为0时,说明没有任何变量可以访问到这个值,这块内存就可以被回收。
  2. 优点
    • 回收及时,一旦对象的引用计数为0,马上就可以回收内存,不会等到垃圾回收器周期性运行时才回收。
    • 不需要像标记清除算法那样暂停应用程序的执行,对应用程序的性能影响相对较小,在一些实时性要求较高的场景(如动画、游戏等)有一定优势。
  3. 缺点
    • 无法处理循环引用的问题。例如两个对象相互引用,即使它们从根对象出发无法访问,但引用计数永远不会为0,导致内存无法回收。
    • 引用计数的维护需要额外的开销,每次变量赋值、解除引用等操作都需要更新引用计数,这增加了程序运行的时间开销。