Dr.*_*ABT 20 javascript arrays
我有一个小循环的代码,它抛出 Uncaught RangeError: Invalid Array Length
\n我能够在 Google Chrome 控制台中重现它
\nconst COUNT = 100_000_000;\nconst xValues = new Array(COUNT);\nconst yValues = new Array(COUNT);\nfor (let i = 0; i < COUNT; i++) {\n xValues[i] = i;\n yValues[i] = Math.sin(i * 0.000001);\n}\nconsole.log(`count: ${yValues.length}`);\nRun Code Online (Sandbox Code Playgroud)\n这是开发者控制台中的输出
\n\n据我所知,Javascript 中的最大数组大小是 2^32-1?应该有足够的内存可以在这里分配,并且索引 i 永远不会是负数或超出数组的范围,据我所知。
\n奇怪的是,如果我使用这段代码,就不会发生崩溃
\nconst COUNT = 100_000_000;\nconst xValues = new Array(COUNT);\nconst yValues = new Array(COUNT);\nfor (let i = 0; i < COUNT; i++) {\n xValues[i] = i;\n yValues[i] = i;\n}\nconsole.log(`count: ${yValues.length}`);\nRun Code Online (Sandbox Code Playgroud)\n\n分配给 yValues[i] 的值永远不会超出 -1, +1 范围,因此我也不能将其视为数字超出范围问题。
\n有人对此有任何了解吗?
\n编辑:更新
\n另一种情况不起作用。计算随机游走。
\n const count = 100_000_000;\n const xValues = new Array(COUNT);\n const yValues = new Array(COUNT);\n let prevYValue = 0;\n for (let i = 0; i < COUNT; i++) {\n const curYValue = Math.random() - .5;\n\n xValues[i] = i;\n yValues[i] = prevYValue + curYValue;\n\n prevYValue += curYValue;\n }\nRun Code Online (Sandbox Code Playgroud)\n这个也能扔!但
\n yValues[i] = i \nRun Code Online (Sandbox Code Playgroud)\n没问题 \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf
\n编辑:更新2
\n现在可以确认这是特定于浏览器的,如果您在 Firefox 中运行相同的测试,它可以工作,但浏览器会要求您等待。
\n怀疑异常Uncaught RangeError是错误报告的超时?
真正的原因在于V8内存优化。当您存储整数时,它会就地存储 32 位数字,但是当您存储双数时,它会以不同的方式存储(作为对象),因此yValues数组包含引用,但实际值存储在堆中。因此,在您的示例中,您刚刚使用了所有堆内存。要查看限制,请使用:console.memory,您将看到类似以下内容:
MemoryInfo\xc2\xa0{\ntotalJSHeapSize: 10000000, \nusedJSHeapSize: 10000000, \njsHeapSizeLimit: 3760000000}\nRun Code Online (Sandbox Code Playgroud)\n在我的浏览器中是3_760_000_000
堆上的对象占用 50+ 字节,因此我的限制约为 69_000_000 个浮点数。
\n