---
url: https://sugarat.top/interview/js/v8garbage.md
---

# V8 下的垃圾回收机制是怎么样的？

垃圾回收会暂停JS运行，如果内存过大会导致垃圾回收时间变长，从而导致JS暂停时间变长

V8 实现了准确式 GC，GC 算法采用了分代式垃圾回收机制。V8 将内存（堆）分为两部分:

* 新生代
  * 64:32MB
  * 32:16MB
* 老生代
  * 64:1400MB
  * 32:700MB

## 新生代算法

新生代中的对象一般存活时间较短

在新生代空间中，内存空间分为两部分，分别为 From 空间和 To 空间。在这两个空间中，必定有一个空间是使用的，另一个空间是空闲的。新分配的对象会被放入 From 空间中，当 From 空间被占满时，新生代 GC 就会启动了。算法会检查 From 空间中存活的对象并复制到 To 空间中，如果有失活的对象就会销毁。当复制完成后将 From 空间和 To 空间互换，这样 GC 就结束了。

## 老生代算法

老生代中的对象一般存活时间较长且数量也多，使用了两个算法，分别是`标记清除算法`和`标记压缩(整理)算法`。

* 新生代中的对象如果经历过一次 Scavenge 算法，会将对象从新生代空间移到老生代空间中。
* 新生代空间中的To 空间的对象占比大小超过 25 %。在这种情况下，为了不影响到内存分配，会将对象从新生代空间移到老生代空间中。

**优先使用[标记清除算法](./../../bigWeb/js/garbage#标记-清除算法)**

* 某一个空间没有分块的时候
* 空间中被对象超过一定限制
* 空间不能保证新生代中的对象移动到老生代中

**标记整理**

* 空间不足以分配新生代晋升对象时，才会触发`标记整理`
* 解决标记清除带来的内存碎片的问题，在标记清除的基础上进行修改
* 将活着的对象向内存区的一端移动，移动完后清理边界外的内存
