详解Node V8引擎的内存和GC
更新时间:2023-10-03Node V8引擎的内存管理
Node.js 基于 Google 的 V8 引擎构建,因此与 V8 共享内存管理和垃圾回收机制。V8 使用堆内存来管理 JavaScript 对象的内存。堆内存分为两个部分:新生代和老生代。新生代堆内存用于存放短期存在的对象,而老生代堆内存用于存放长期存在的对象。
在具体实现上,Node.js 为了支持常见的 Web 服务器场景,使得使用大量短时间生命周期的对象,常驻内存的对象尽量少。因此在 Node.js 中,将堆内存分为两部分时,并没有简单地将堆内存分为两个等份。而是使用了一种称为垃圾回收的技术,以自动管理内存,避免内存泄漏。
// Node.js 中代码演示 const arr = []; for (let i = 0; i < 100000000; i++) { arr.push(i); }
新生代GC
堆内存中新生代部分通常占堆内存的 1% 到 10% 左右,因此称为小堆。Node.js 使用了一种名为 Scavenger(清道夫)的垃圾回收器来管理新生代堆内存。
在新生代堆内存中,内存分为两个区域:From 空间和 To 空间。From 空间用于存放当前正在使用的对象,而 To 空间则为空闲状态,等待内存占用比较高时,将 From 空间的存活对象复制到 To 空间中,然后清理掉 From 空间。
// Node.js 中代码演示 const arr = []; for (let i = 0; i < 100000; i++) { arr.push(i); }
老生代GC
堆内存中老生代部分通常占用的内存较多(通常是 1GB 左右),因此称为大堆。Node.js 使用一种名为标记清除(Mark-Sweep)的垃圾收集器来管理老生代堆内存。
在标记清除算法中,首先通过根节点遍历所有对象,将所有可以访问到的对象标记为存活对象。然后,遍历整个堆内存,清理未被标记的对象。
// Node.js 中代码演示 let arr = []; for (let i = 0; i < 100000000; i++) { arr.push(i); } arr = null;
总结
Node.js 基于 V8 引擎构建,共享 V8 引擎的内存管理和垃圾回收机制。V8 使用堆内存来管理 JavaScript 对象的内存。将堆内存分为新生代和老生代,使用垃圾回收算法来自动管理内存。Node.js 的内存管理机制,避免了内存泄漏和内存溢出等问题。