【问题标题】:Are there limits to the number of properties in a JavaScript object?JavaScript 对象中的属性数量是否有限制?
【发布时间】:2012-03-06 04:10:40
【问题描述】:

我们有一个包含 75000 多个属性的对象。对象的格式如下:

// The key starts with 3 letters and then is followed by 8 numbers
var bigArray = {'AAA########':123456789,
                'AAA########':123456790,
                'AAA########':123456791
               }; 

JavaScript 对象的属性数量是否存在已知限制?根据我的测试,该对象在 65500 个元素上仍然有效。

  • 在 Windows 7 中,IE9 脚本崩溃(错误 -2147024882)。
  • Windows XP、IE8 运行良好。

【问题讨论】:

标签: javascript object properties


【解决方案1】:

在当前版本的 Chrome(2017 年 9 月)中,我限制在大约 830 万键。尝试将其粘贴到浏览器控制台中:

let obj = {};
let keyCount = 0;
while(1) {
  obj[Math.random()] = Math.random();
  if(++keyCount % 10000 === 0) console.log(keyCount);
}

我在 Node.js 中得到了相同的限制:

node --max-old-space-size=20000 -e "let obj = {}; let keyCount = 0; while(1) { obj[Math.random()] = Math.random(); if(++keyCount % 10000 === 0) console.log(keyCount); }"

有趣的是,如果我使用 Map,我可以在它崩溃之前获得大约 1680 万 个密钥(您可以使用 this 之类的东西超过这个限制)。

【讨论】:

  • 现在是 2020 年,我的收入也在 830 万左右。
  • 对于地图,1680 万限制可能基本上是这个 2^24 限制bugs.chromium.org/p/v8/issues/detail?id=11852 而对于对象,8.3M 可能是对象上的 2^23(在这种情况下似乎挂起多于产生特定的错误消息)
【解决方案2】:

我不确定 实际 值是多少,但我在 node.js 中看到 实际 上限约为 400,000(在具有 16 GB RAM 的 Mac 上) )。

这是我将数据库中的行添加到对象中的日志:

[[21:32:34.325]] [LOG] 340001, pint of delight
[[21:32:35.574]] [LOG] 350001, pound shrimp
[[21:32:36.545]] [LOG] 360001, ravioli allaragosta
[[21:32:37.721]] [LOG] 370001, roasted ham and cheese
[[21:32:39.862]] [LOG] 380001, salmon kama
[[21:32:41.152]] [LOG] 390001, scallops and vegetables
[[21:32:42.150]] [LOG] 400001, show cabernet ca
[[21:32:44.412]] [LOG] 410001, sloppy nachos
[[21:33:25.425]] [LOG] 420001, spaghetti or ziti sauce
[[21:35:37.839]] [LOG] 430001, steak au poivre vert
[[21:37:37.202]] [LOG] 440001, sushi moriawase
[[21:39:45.365]] [LOG] 450001, tequila shooters
[[21:42:09.036]] [LOG] 460001, toro roll with scallion
[[21:44:32.796]] [LOG] 470001, two enchiladas taco rice and refried beans
[[21:47:02.584]] [LOG] 480001, veuve clicquot ponsardin rose reims nv
[[21:49:04.020]] [LOG] 490001, whole turkey gourmet sides
[[21:51:15.264]] [LOG] finished

直到大约 400,000 条,插入 10,000 条新记录大约需要 1 秒。超过 410,000,时间几乎呈指数增长。

我不确定如何解决这个问题。也许制作 2 个对象并将它们每个限制为 400,000 个键...有点劳动密集型但比重写字典对象要好:)

更新: 看起来问题实际上是 使用的内存量,而不是对象的数量。我的机器在使用了大约 1.5 GB 的 RAM 时慢了下来。它可能与分配给 node.js 进程的内存相关联,可以通过以下参数增加内存:--max_old_space_size=4096(数字以 MB 为单位)。

【讨论】:

  • 您知道 4gb 是用于所有 NodeJS 安装还是仅取决于您自己的计算机?
  • 不确定,但我总共有 16GB RAM - 您可以调整 --max_old_space_size 参数;多么奇怪的名字啊……!
【解决方案3】:

由于 Javascript 的内存限制,数组的确切最大限制为 2^32 - 1 或 4294967295。

Link

【讨论】:

  • OP 没有使用数组,他只是声明了一个大对象。
  • 嗯,我猜任何类型都会受到 Javascript 内存的限制,不是吗?
【解决方案4】:

从我们对这个问题的测试来看,IE9、Windows 7 似乎将 HTA 脚本中的行数限制为 65535。我没有找到关于这个问题的任何来源,这只是我们测试的结果。

【讨论】:

    【解决方案5】:

    它将是 2^32 - 1;但是,特定的浏览器可能会进一步限制它。

    【讨论】:

      【解决方案6】:

      在具有 16gb 内存的 Windows 10 上使用 Deno 版本 1.6.2 进行测试。

      Javascript 对象 最大键数:116.597.277

      deno eval "let obj = {}; let keyCount = 0; while(1) { ++keyCount; obj[keyCount] = keyCount; if(keyCount % 10000 === 0 || keyCount > 116590000) console.log(keyCount); }"
      

      映射最大键数:116.597.277

      deno eval "let obj = new Map(); let keyCount = 0; while(1) { ++keyCount; obj[keyCount] = keyCount; if(keyCount % 10000 === 0 || keyCount > 116590000) console.log(keyCount); }"
      

      我在 Edge 版本 87.0.664.66 和 Chrome 版本 87.0.4280.88 测试 Javascript 对象和地图时获得了相同的数字。

      【讨论】:

      • 我认为您在这里看到的是幕后优化,因为您使用连续整数作为键。如果您使用随机密钥,截至 2021 年 3 月,您仍然会获得比 830 万低得多的限制(刚刚在 Deno、Node 和 Chromium 中进行了测试)。
      • @joe 你是对的,只需在键中添加一个字符串(将 obj[keyCount] = keyCount; 更改为 obj['a'+keyCount] = keyCount;)给我同样的结果 830 万(代码只是停止工作,不'不退出整数键异常)
      • 请参阅此处查看 chrome/nodejs/v8 bugs.chromium.org/p/v8/issues/detail?id=11852
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 2020-06-21
      • 2011-12-17
      • 1970-01-01
      • 2013-10-18
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多