Javascript/Node.js 引擎如何在内存中存储 JSON?

How Javascript/Node.js engine store JSON in memory?

我有一个 70 MB 的 JSON 文件,我从 Node.js 脚本中读取它并分配给一个变量。

console.log(process.memoryUsage());
let data=require('../newJSON.json');
console.log(process.memoryUsage());

输出:

{ rss: 28184576,
  heapTotal: 6283264,
  heapUsed: 4199672,
  external: 8252 }
{ rss: 724721664,
  heapTotal: 695595008,
  heapUsed: 663708016,
  external: 8252 }

70 MB JSON 似乎需要 632 MB 内存。我有兴趣了解 Node Js/Javascript 如何将 JSON 存储到内存中?

首先,JSON 只是对象的字符串表示。 "JSON objects" 没有什么特别之处——JSON 解析器解析 JSON 字符串并从中创建常规 JavaScript 对象。这个:

var a = JSON.parse('{"foo": "bar"}');

还有这个:

var a = new Object(); a.foo = "bar";

完全等价。


内存中的对象存储很复杂,因为现代 JavaScript 引擎根据您的代码正在执行的操作针对各种不同情况进行了非常漂亮的优化。

JSON字符串长度和内存中对应对象的大小没有严格的相关性;在大多数情况下,JSON 表示预计会更小,有时会小很多。例如。对于您的示例的最内层嵌套:"a":0, 占用 6 个字节,而对于创建的对象中的另一个 属性,您需要:

  • 一个指向 属性 名字的指针,"a"
  • 属性 属性的一个指针(可写、可枚举、可配置)
  • 属性 值的一个指针,0
  • 假设对象处于字典模式:平均而言,大约有两个松弛指针

在 64 位平台上,总计约 40 个字节。

如果您查看整个类似形状的对象:{"a":0,"b":1} 是 13 个字符,而内存要求是:

  • "map"指针
  • "elements" 指针(未使用)
  • 对象外"properties"指针(未使用)
  • 第一个值 属性 (0)
  • 秒值 属性 (1)
  • 对象的"map":11个指针(可以与其他相同形状的对象共享,但如果只有一个这样的对象,则没有任何对象可以共享)
  • 对象映射的属性描述符:10个指针

总共有 26 个指针或 208 个字节。

最后,您看到的一些内存使用量可能来自 GC 会随着时间的推移清理的临时对象。