Node系列 — v8引擎堆内存详解

发布时间 2023-10-12 19:04:38作者: 吴飞ff

参考:https://juejin.cn/post/6963170647207837710

v8 的堆内存限制

Node 程序中 javascript 的使用内存是有限制的,注意这个内存是指堆内存,在v8中,所有的 js 对象都存在堆中。在实际应用中不小心触碰到这个边界,进程就会退出。64位系统下为1.4GB,32位系统下为0.7GB。 Node 是基于 v8 引擎构建,所以 v8 会通过自己的方式来进行内存的分配和管理。 那么问题来了:

  • 为什么要对 v8 堆内存进行限制?
  • 为什么内存的大小控制在 1.4GB or 0.7GB ?

v8 的对象分配

内存查询

Node 提供了 process.memoryUsage() 方法,返回描述 Node.js 进程的内存使用情况(以字节 Bytes 为单位)的对象。 执行以下代码可以查看内存的使用情况:

$ node
> process.memoryUsage()
{
  rss: 29196288,
  heapTotal: 5685248,
  heapUsed: 4549120,
  external: 926086,
  arrayBuffers: 10077
}

解释一下这些字段:

      rss: 常驻集大小, 是为进程分配的物理内存(总分配内存的子集)的大小,包括所有的 C++ 和 JavaScript 对象与代码。

      heapTotal: v8 已申请的堆内存大小。

      heapUsed: 当前堆内存已使用的大小。

      external: 代表 V8 管理的绑定到 Javascript 对象的 C++ 对象的内存使用情况。

      arrayBuffers: 代表分配给 ArrayBuffer 和 SharedArrayBuffer 的内存,包括所有的 Node.js Buffer。

 

重点:在实际业务中,我们声明的每一个变量对象都被分配在堆中,如果已申请的堆中空闲内存不够分配新的对象,将继续申请堆内存,直到超出 v8 的限制
 

内存上限默认值

在《深入浅出Nodejs》中说明,64位系统约为1.4GB,32位系统约为0.7GB。
我根据本地几个 node 版本亲自测试了一下: 创建 memorySize.js:

const v8 = require('v8')
console.log('HeapStatistics:',v8.getHeapStatistics()) // 查询堆内存上限设置

结果:

HeapStatistics: {
  total_heap_size: 4284416,
  total_heap_size_executable: 524288,
  total_physical_size: 3122176,
  total_available_size: 4342823264,
  used_heap_size: 3384776,
  heap_size_limit: 4345298944, // 4.04G
  malloced_memory: 254120,
  peak_malloced_memory: 90736,
  does_zap_garbage: 0,
  number_of_native_contexts: 1,
  number_of_detached_contexts: 0
}

修改堆内存默认值