V8引擎的垃圾回收机制 | 青训营笔记

69 阅读2分钟

V8引擎的垃圾回收机制采用了分代垃圾回收的策略。这里的“分代”指的是将内存中的对象分为新生代和老生代两个代。在新生代,对象的生命周期短暂,大多数对象被分配出去后会很快变得无用。因此,V8引擎会将新生代中的对象放入临时堆中。临时堆中的对象在内存中是连续排列的,分配和回收也很快速。 新生代的垃圾回收通常采用Scavenge算法,该算法基于Cheney算法。Scavenge算法将新生代内存根据大小分为等大小的两个区域,一个区域用于存放活动对象,另一个区域用于垃圾回收。当一个对象需要被分配时,先将这个对象分配到FromSpace的空间。当FromSpace被慢慢填满时,V8引擎会暂停JavaScript应用程序的执行,然后将FromSpace中还存活的对象复制到ToSpace中。同时,FromSpace和ToSpace进行角色交换,ToSpace成为新的FromSpace,FromSpace成为空闲区域。垃圾回收完成后,应用程序重新开始执行。 经过两次scavenge算法仍然存活的对象,晋升为老生代。 老生代的垃圾回收机制主要有以下两个步骤。

  1. 标记-清除:标记-清除算法是V8引擎最早的老生代垃圾回收算法,通过标记与清除相结合的方式对老生代进行垃圾回收。具体而言,它会将堆中的所有对象标记一遍, 对老生代对象进行第一次扫描,对活动对象进行标记 ,然后,对老生代对象进行第二次扫描,清除未标记的对象,即非活动对象。但是,这种算法会产生内存碎片,需要额外的空间来避免碎片。
  2. 压缩(Mark-Compact):压缩算法是一种优化标记-清除算法的垃圾回收算法,它在标记-清除阶段结束后,将存活的对象进行整理,并将它们集中移动内存的一侧中,释放出不连续的内存空间。该算法较好地解决了标记-清除算法的内存碎片问题,并提高了程序的内存使用效率。