V8与垃圾回收机制

5 阅读2分钟
强引用和弱引用

在JS里面默认的引用都是强引用,一个变量如果存在强引用则不会被垃圾回收机制回收,但是如果一个变量强引用都不存在了,只剩下弱引用,则不会阻止垃圾回收机制回收对象

弱引用的主要方式为:WeakMap和WeakSet

最常见的用途是DOM绑定依赖。如果使用Map绑定响应式变量和依赖的关系,会导致只要Map存在,DOM里涉及的变量和依赖就不会被回收,这就容易导致内存泄漏,但是WeakMap则不会。

但是WeakMap和WeakSet相对于Map和Set的限制:

  1. key必须是对象,不能是基本类型(所以响应式变量存的是整个ref)!
  2. 没有常规的forEach、keys、values等遍历方法,也没有size属性
  3. 没办法手动clear清空,只能依赖垃圾回收机制自动清空

最常见的应用场景:

  1. 依赖管理
  2. 处理循环引用导致的无法回收问题
  3. 给DOM添加临时标记
垃圾回收机制
  • 垃圾回收的算法主要有两种:引用计数法 和 标记清除法

引用计数法:每个对象维护一个引用计数器,每次新增一个强引用的时候计数器+1,每次解除强引用的时候,计数器-1,计数器为0的时候回收该对象。

标记清除法:从根对象进行遍历,给能达到的对象进行标记,如果对象没有标记,则被垃圾回收机制清除。标记清除的重点是可达性分析,避免了中间对象互相引用导致的引用计数持续不会归0问题。

除此还有新生代以及老生代等概念,也就是垃圾回收机制将内存分为From(新生代区)和To(老生代区),一到两次被确定没有标记,需要清除的对象进入到新生代区,三到五次垃圾回收机制下依然没有被索引的对象进入到老生代区,老生代区的变量优先被清除。