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

ana*_*and 11 javascript json memory-management v8 node.js

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

console.log(process.memoryUsage());
let data=require('../newJSON.json');
console.log(process.memoryUsage());
Run Code Online (Sandbox Code Playgroud)

输出:

{ rss: 28184576,
  heapTotal: 6283264,
  heapUsed: 4199672,
  external: 8252 }
{ rss: 724721664,
  heapTotal: 695595008,
  heapUsed: 663708016,
  external: 8252 }
Run Code Online (Sandbox Code Playgroud)

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

jmr*_*mrk 6

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

var a = JSON.parse('{"foo": "bar"}');
Run Code Online (Sandbox Code Playgroud)

还有这个:

var a = new Object(); a.foo = "bar";
Run Code Online (Sandbox Code Playgroud)

是完全相同的.


内存中的对象存储很复杂,因为现代JavaScript引擎根据您的代码所做的事情,针对各种不同情况进行了非常好的优化.

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

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

在64位平台上,最多可增加约40个字节.

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

  • "地图"指针
  • "元素"指针(未使用)
  • out-of-object"属性"指针(未使用)
  • 第一财产的价值(0)
  • 第二财产的价值(1)
  • 对象的"地图":11个指针(可以与相同形状的其他对象共享,但如果你只有一个这样的对象,则无需与之分享)
  • 对象的地图属性描述符:10个指针

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

最后,您看到的一些内存使用情况可能来自GC将随着时间的推移而清理的临时对象.