San Baofeng's

Javascript-Garbage-Collection

这篇聊聊 JavaScript 的垃圾收集。

垃圾就是,程序执行之后不在需要的需要从内存中释放的变量。JavaScript 具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。

垃圾收集的原理

找出不再继续使用的变量,然后释放其占用的内存。

垃圾收集器会按照固定的时间间隔(或代码执行中预订的收集时间),周期性地执行这个操作

局部变量的正常生命周期

局部变量只存在函数的执行过程中。在这个过程中,会为局部变量在栈或堆上分配相应的内存空间,方便它们存储值,在函数中使用这些变量,直到函数执行结束。

两种垃圾收集策略

  1. 标记清除
  • 垃圾收集器在运行的时候回给存储在内存中的所有变量都加上标记
  • 去掉环境中的变量以及被环境中的变量引用的变量的标记
  • 在上一步之后,再次打上标记的变量,将被视为准备删除的变量
  • 垃圾收集器销毁带标记的值,回收它们占用的内存空间

几乎所有浏览器都采用这种垃圾收集策略

  1. 引用计数:追踪记录每个值被引用的次数
  • 声明变量并将一个引用类型赋值给这个变量时,这个值的引用次数为1
  • 同一个变量又被赋值给另一个变量,引用次数加1
  • 包含对这个值引用的变量又取得另一个值了,则这个值引用次数减1
  • 当引用次数为0时,说明没有办法再访问这个值了
  • 垃圾收集器下次再运行时,将其内存空间回收回来

循环引用的问题

1
2
3
4
5
6
7
function problem () {
var objA = new Object();
var objB = new Object();

objA.someOtherObject = objB;
objB.anotherObject = objA;
}

objA 和 objB 通过各自的属性相互引用,导致两个对象的引用次数都是2,函数执行完成之后,这两个对象的内存无法回收。

解除变量的引用不仅有助于消除循环引用现象,而且对垃圾回收也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。

摘自:《高程》第四章-4.3 垃圾收集