Skip to content
On this page

垃圾回收机制

在 JS 引擎中,设置了垃圾回收器负责在代码执行时管理内存,因此不需要开发者手动管理内存。 其原理主要是周期性检查变量是否会再使用,进而释放其内存回收闲置资源。

可达性(Reachability

JavaScript 中主要的内存管理概念是可达性:即变量是储存在内存中的,可通过某种方式访问使用的值。 当变量在程序中不再被引用,那么我们就认为该变量是不可达的,符合垃圾回收的条件,可以释放其内存。 其中有部分变量作为浏览器或者引擎应用的的对象而不应被释放,这类变量被称为根对象Roots) 一般分为:

  • 全局变量
  • 当前函数的局部变量和参数
  • 浏览器对象(如 DOM 元素)
  • 其他内部变量

引用计数

对每个值记录其被引用的次数,当被赋给一个引用值时,引用数加一,保存对该值引用的变量被其他值给覆盖时,引用数减一。当一个值的引用数为 0 时即代表可以安全地收回其内存。垃圾回收程序将在下次运行时释放其内存。

这种策略主要于 IE8 及更早的 IE 版本 中使用。且当出现循环引用(无论是 JS 对象还是 DOM 对象)时,便会出现引用数永远不会变成 0 的情况而导致内存不会被释放,甚至出现内存泄漏问题。

标记清理

当变量进入上下文,比如在函数 内部声明一个变量时,这个变量会被加上存在于上下文中的标记。而在上下文中的变量,逻辑上讲,永远不应该释放它们的内存,因为只要上下文中的代码在运行,就有可能用到它们。当变量离开上下文时,也会被加上离开上下文的标记。

这是现代浏览器所采用的策略(具体实现各有所异)。标记清除最大的优点就是解决了循环引用的问题,但也存在一定的缺点:当一个变量不再被引用,即不可达时,垃圾回收器并没有立即进行回收,而是先标记,在下一轮再清理,这也会造成一定的空间浪费。

Last updated: