# 浏览器的垃圾回收

# 什么是垃圾数据?

  • 在写js代码时,会频繁操作数据,在一些数据不被需要的时候,这些就是垃圾数据, 垃圾数据暂用的内存就应该被回收。

# 垃圾回收算法

  • 从根节点出发,遍历并标记可达的数据,然后移除不可达的数据。
  • 在频繁的回收后,会出现大量不连续的内存,叫内存碎片。然后需要整理这些碎片。

# 什么时候垃圾回收?

  • 垃圾回收的时候需要暂停js脚本,等垃圾回收后再继续进行。

# 分代收集

  • 浏览器将数据分为两种,临时对象和长久对象 临时对象,大部分在内存中存活的时间较短,很快变得不可访问,应该快点回收。 长久对象,生命周期很长的对象,比如window,DOM,web api等。应该慢点回收。 这两种对象分别对应不同的回收策略,V8将堆分为新生代和老生代两个区域,新生代中存放临时对象,老生代存放长久对象。 并且让副垃圾回收器和主垃圾回收器分别回收新生代和老生代的垃圾。

# 主垃圾回收器

  • 负责老生代的垃圾回收,有两个特点,对象占用空间大,存活时间长。使用 标记-清除 算法执行垃圾回收。 会产生内存碎片,最后需要内存整理。

# 副垃圾回收器

  • 负责新生代垃圾回收,通常只支持1-8M容量。
  • 新生代被分为两个区域,对象区,空闲区。
  • 新加入的对象都放入对象区,当对象区域快满的时候,会执行一次垃圾清理。
    1. 先给对象区域所有垃圾做标记
    2. 标记完成后,将存活的对象复制到空闲区,并将他们有序的排列(所以最后没有碎片整理)。
    3. 复制完成后,对象区会跟空闲区进行对调,将空闲区存活的对象放入对象区。
  • 因为副垃圾回收器操作比较频繁,所以为了执行效率,一般新生区的空间会被设置的比较小。

# 增量收集

  • 如果脚本中有很多对象,引擎一次性遍历整个对象,会造成长时间的暂停,所以引擎将垃圾收集工作分为更小的块, 每次处理一部分,多次处理。

# 闲时收集

  • 只在CPU空闲时进行回收,以减少对代码执行的影响。