Chrome、Node.js幕后英雄V8引擎的垃圾回收(上)
2023-10-06 20:11:50
V8引擎是时下炙手可热的JavaScript引擎,它的足迹不仅遍布Chrome,Node.js等浏览器领域,也逐步在Deno等新贵中占据着一席之地。
国庆假期,身处厦门的笔者积极响应防疫政策,遂在家中潜心学习。在此期间,笔者新习得了关于V8引擎垃圾回收机制的知识,现分享给大家。
该机制分为两部分,本篇主要介绍V8的内存分配、大小及新生代垃圾回收算法“scavenge”。
对于从事前端开发、Node.js开发的朋友,相信V8并不陌生。但对于其运作原理,可能还有很多未知之处。这篇文章将带你深入了解V8引擎的内部构造。
那么话不多说,让我们从一个关键问题开始:V8引擎是如何管理内存的?
V8的内存分配
V8引擎采用分代垃圾回收算法,将内存分为新生代和老年代。
新生代存储着最近分配的对象,由于这些对象存活时间较短,因此垃圾回收频率较高。老年代存储着存活时间较长的对象,其垃圾回收频率较低。
V8引擎在新生代中使用“scavenge”算法进行垃圾回收。该算法将新生代内存划分为两个半空间:From Space和To Space。
From Space用于存储活动对象,而To Space则为空闲。当From Space空间不足时,会触发一次scavenge。
V8新生代大小
V8引擎会根据程序的内存使用情况动态调整新生代的大小。
新生代大小的初始值为2MB,最大值为8MB。当新生代中活动对象所占的内存超过新生代总内存的25%时,V8引擎会将新生代大小增加一倍。
当新生代中活动对象所占的内存低于新生代总内存的12.5%时,V8引擎会将新生代大小减半。
scavenge算法
scavenge算法的原理是将From Space中的活动对象复制到To Space中,然后将From Space中的所有对象标记为可回收。
具体步骤如下:
- 将From Space中的所有指针指向To Space中的对应对象。
- 遍历From Space,将所有对象标记为可回收。
- 将To Space和From Space交换,使To Space成为新的From Space,From Space成为新的To Space。
scavenge算法的优点是速度快,因为只需要复制活动对象,而不需要遍历所有对象。
但scavenge算法的缺点是会产生内存碎片。为了解决这个问题,V8引擎会在新生代中使用“mark-sweep”算法进行压缩。
mark-sweep算法的原理是首先标记所有活动对象,然后释放未标记的对象所占用的内存。
mark-sweep算法的优点是不会产生内存碎片,但其速度较慢。
V8引擎会根据新生代中活动对象的分布情况,选择使用scavenge算法还是mark-sweep算法进行垃圾回收。
文章到此结束,下篇将介绍V8引擎的老年代垃圾回收算法“mark-sweep-compact”。
保持关注,下篇见!