【问题标题】:How Javascript/Node.js engine store JSON in memory?Javascript/Node.js 引擎如何将 JSON 存储在内存中?
【发布时间】:2017-12-13 20:54:00
【问题描述】:

我有一个 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 保存为 .js 文件,其中唯一的内容是 module.exports = <json>,那么它甚至会占用大约 2 倍的内存!
  • 是的!对我来说module.exports 导致了 FatalProcessOutOfMemory 问题。
  • 它是什么样的 JSON,结构和平均元素大小是多少?
  • 在我的例子中,它是一个带有 5 个子级别的嵌套 JSON。
  • 例如:{"8 char": {''6 char": {"1 char": { "8 char": {"1 char":<0 or 1> ,"1 char":<0 or 1>} } } } }。 (8 char : 平均 8 个字符)

标签: javascript json node.js memory-management v8


【解决方案1】:

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

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

还有这个:

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

完全等价。


内存中的对象存储很复杂,因为现代 JavaScript 引擎根据您的代码正在做什么,针对各种不同的情况进行了相当不错的优化。

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

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

在 64 位平台上,加起来最多为 ~40 个字节。

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

  • “地图”指针
  • “元素”指针(未使用)
  • 对象外“属性”指针(未使用)
  • 第一个属性的值 (0)
  • 第二个属性的值 (1)
  • 对象的“地图”:11 个指针(可以与其他形状相同的对象共享,但如果您只有一个这样的对象,则没有任何可共享的对象)
  • 对象映射的属性描述符:10 个指针

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-28
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多