javascript 的垃圾回收机制

123 阅读2分钟

原理

js代码想要运行,需要操作系统或者运行时提供内存空间,来存储变量及它的值,在某些变量(例如局部变量)在不参与运行时,就需要系统回收被占用的内存空间,找到不再被使用的变量,然后释放其占用的内存,但这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定时间间隔周期性的执行——————称为垃圾回收

回收方式

  • 标记清除

当变量进入执行环境时,标记这个变量为“进入环境”;当变量离开环境时,标记为“离开环境”;垃圾回收器并不是每时每刻都在工作,每隔一段时间工作一次;垃圾回收器运行时,给每个变量都加上标记,然后去掉环境中的变量,以及被环境中变量引用的变量的标记。然后,这时候,剩下的所有的被标记的变量,都是要被清除回收的变量。最后,垃圾收集器销毁这些变量的值,收回占用的内存空间。

  • 引入计数(低级浏览器,不太常见)

引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。这样,垃圾收集器下次再运行时,它就会释放那些引用次数为0的值所占的内存。

内存泄露

内存泄露:某些情况下,不再用到的变量所占内存没有及时释放,导致程序运行中,内存越占越大,极端情况下可导致系统崩溃、服务器宕机

  1. 意外的全局变量引起的内存泄露
  • 原因: 全局变量不会被回收

  • 解决:使用严格模式避免

  1. 闭包引起的
  • 原因: 活动对象被引用,使闭包内的变量不会被释放

  • 解决: 将活动对象赋值为null

  1. 被清理的DOM元素的引用
  • 原因: 虽然DOM被删掉了,但对象中还存在对DOM的引用

  • 解决: 将对象赋值为null

  1. 被遗忘的定时器或回调
  • 原因: 定时器内部实现闭包,回调也是闭包

  • 解决: 清理定时器clearInterval、null

避免垃圾回收

  1. 对象尽量复用,不用的对象尽量赋值为null
  2. 循环优化