【问题标题】:In V8 why does a preallocated array consume less memory?在 V8 中,为什么预分配的数组消耗更少的内存?
【发布时间】:2017-02-22 22:38:32
【问题描述】:

考虑以下两种选择:

  const mb_before = process.memoryUsage().heapUsed / 1024 / 1024;
  const n = 15849;
  const o = 115;
  const entries = [];
  for (var i = 0; i < n; i++) {
    const subarr = [];
    for (var j = 0; j < o; j++) {
      subarr.push(Math.random());
    }
    entries.push(subarr);
  }
  const mb_after = process.memoryUsage().heapUsed / 1024 / 1024;
  console.log('arr using ' + (mb_after - mb_before) + ' megabyte');
  // arr using 15.110992431640625 megabyte

  const mb_before = process.memoryUsage().heapUsed / 1024 / 1024;
  const n = 15849;
  const o = 115;
  const entries = new Array(n);
  for (var i = 0; i < n; i++) {
    const subarr = new Array(o);
    for (var j = 0; j < o; j++) {
      subarr[j] = Math.random();
    }
    entries[i] = subarr;
  }
  const mb_after = process.memoryUsage().heapUsed / 1024 / 1024;
  console.log('arr using ' + (mb_after - mb_before) + ' megabyte');
  // arr using 12.118911743164062 megabyte

据我了解,这两个数组的大小应该相同,只是它们的实例化方式不同。如何解释导致的内存使用量始终不同?

【问题讨论】:

  • 一句话?优化。
  • @T.J.Crowder 感谢您的更正;仍然想知道如何根据数组实例化的方法以不同的方式优化数据量的持久性
  • 对不起,我删除的评论并不是作为一个更正,只是作为一个大学笑话。抱歉,如果没有遇到。

标签: javascript arrays memory v8


【解决方案1】:

我相信这与分配数组内存的方式有关。当您像在第二个示例中那样实例化一个为其指定特定大小的数组时,它将分配该内存。

当您扩大阵列时,它会分配少量额外空间来处理增长,然后随着您扩大阵列,额外的内存分配会变得更大。这会在第一个示例中产生额外的可用空间。

【讨论】:

  • (这里是 V8 开发人员)这是正确的。当您使用Array(n) 构造函数时,V8 可以根据您的需要完全分配空间。当您创建一个空数组(使用[]new Array())并继续向其中添加元素时,V8 会以块的形式增长后备存储,因此在您停止添加元素时,可能仍有一些未使用的预分配后备商店。
【解决方案2】:

我一点也不觉得这令人惊讶。尽管标准数组aren't really arrays at all*,JavaScript 引擎默认优化:尽可能将它们视为真正的数组。

在您的第一个示例中,V8 不知道每个数组会变得多大 - 它只是不断增长,为了将其视为优化数组(而不是具有特殊属性的对象),V8必须定期重新分配和复制以使其更大。因此,最近的主动分配留出大量额外空间以防它继续增长也就不足为奇了。

在您的第二个示例中,您已经提前为 V8 提供了一个重要的旧线索,说明您打算制作多大的数组。因此,V8 使用该信息来优化它对底层真实数组的分配是合理的。


* (这是我贫血的小博客上的帖子)

【讨论】:

    猜你喜欢
    • 2017-07-17
    • 2016-08-15
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    • 2012-08-12
    • 1970-01-01
    相关资源
    最近更新 更多