GC

文章目录

V8引擎垃圾回收算法

分代式垃圾回收

  • 新生代:新生代中的对象为存活时间较短的对象
  • 老生代:老生代中的对象为存活时间和数量较多的对象

按照对象的存活时间将内存的垃圾回收进行不同的分代,然后分别对不同分代的内存实行更高效的算法

scavenge 算法(具体实现采用了Cheney算法)—》通过牺牲空间换时间适合生命周期短的新生代

Cheney算法是采用复制方式实现的垃圾回收算法,它将堆内存一分为二,每一部分空间成为semispace。在这两个semispace空间中,只有一个处于使用中,另一个处于闲置状态。处于使用中的成为From空间,处于闲置状态的空间成为To空间。

分配对象时,首先从From空间进行分配,当开始垃圾回收时候,会检查From空间中的存活对象,这些存活对象将被复制到To空间中,而非存活的对象占用的空间将会被释放。完成复制之后,From和To角色互换

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

在老生代中,以下情况会先启动标记清除算法:

  • 空间中对象超过一定限制
  • 空间不够新生代对象转移到老生代中
  • 某一个空间没有分块的时候

Mark-Sweep & Mark-Compact

标记清除算法和标记压缩算法
Mark-Sweep在标记阶段遍历堆中的所有对象,并标记活着的对象,在随后的清除阶段中,只清除没有被标记的对象。
而清除之后出现内存的不连续,需要Mark-Compact进行整理

增量标志

垃圾回收的三种算法都需要将应用逻辑暂停下来,代执行完垃圾收集后再恢复执行应用逻辑,成为“全停顿”,带来体验的影响。

V8从标记阶段入手,将一口气停顿完成的动作改为增量标记。就是拆分为许多小的“步进”,每做完一“步进”,就让JavaScript应用逻辑执行一小会。交替直至完成。

分享到: