JavaScript 内存限制
Posted
技术标签:
【中文标题】JavaScript 内存限制【英文标题】:JavaScript memory limit 【发布时间】:2011-02-25 13:53:16 【问题描述】:javascript 应用程序可以存储的数据量是否有上限?
我猜这是由浏览器处理的,每个都有其局限性?
如果没有限制,是否会创建页面文件?如果是这样,那不是不安全吗?
【问题讨论】:
有一些限制,尽管这些取决于浏览器。例如,Firefox 对堆栈空间以及过多的 CPU 消耗都有限制。 【参考方案1】:AFAIK,没有上限,你的脚本基本上可以使用内存,直到系统内存耗尽(包括交换)。没有上限不代表一定要吃光,用户可能不喜欢。
【讨论】:
【参考方案2】:Javascript 程序没有内存限制。您的脚本可以占用您机器上的所有 RAM。但是,不建议用完用户机器上的所有内存。如果您要处理大量数据,我建议您检查缓存。
【讨论】:
脚本不能占用机器上的所有 RAM。它仍将绑定到底层进程空间。因此,在 32 位浏览器上,只有 4GB 的可寻址内存。 我相信它实际上是 2Gb,至少在某些情况下是这样,所以假设 2GB,它在任何地方都可以正常工作 我意识到这些 cmets 有点老了,但我已经构建了玩具原型,可以使用原生数组获得超过 4GB 的可寻址内存,正如您在出色的答案 @JohnZabroski 中提到的那样。跨度> @Pwpwpw 另外,我不知道 John 是不是在说 Windows,而我不是。是的,我的回答更老了,现在情况会有所不同。 有人运行 32 位浏览器?他们已经预料到现代网页会在那台机器上崩溃。【参考方案3】:在 Chrome 和 Chromium OS 中,内存限制由浏览器定义,您可以在开发者工具命令行中按 F12 使用以下命令检查限制:
> window.performance.memory.jsHeapSizeLimit
1090519040
在我的 Windows 10 操作系统上,它大约为 1 GB。
在 Chrom(e/ium) 上,您可以通过分配原生数组来绕过堆大小限制:
var target = []
while (true)
target.push(new Uint8Array(1024 * 1024)); // 1Meg native arrays
这会使标签在 2GB 左右崩溃,这种情况发生得非常快。之后 Chrom(e/ium) 出现故障,如果不重新启动浏览器就无法重复测试。
我还建议您阅读 TrackJS 关于 Monitoring JavaScript Memory 的博文,然后再深入了解尝试诊断或测量浏览器中与内存相关的任何内容。
您也可以在 comp.lang.javascript 中搜索 javascript memory limit。
另请参阅这些 Stack Overflow 帖子:
Maximum size of an Array in Javascript,这表明您最多可以存储 232-1 = 4,294,967,295 = 42.9 亿个元素。
Maximum number of arguments a JavaScript function can accept
JS9天文影像展示库网站有补充知识:Dealing with Memory Limitations。
(我试图找到一个好的答案,而这里提供的“没有上限”的答案对我来说简直是愚蠢的。我不能在一个价值数百万美元的项目中遇到生产问题并向管理层说, “好吧,我假设没有上限,一切都会好起来的。”尝试做一个概念验证,例如在您选择的 JavaScript UI 框架中加载大量组合框控件等。您可能会发现您的框架有一些performance degradation.)
以下是一些我发现在 CPU 性能和内存性能方面都可以很好扩展的组件:
-
Microsoft Monaco editor
这被几个商业项目使用:
-
邮递员,自 v7.1.1-canary08 起
VS 代码
以下是一些众所周知的性能下降的框架示例:
-
Angular:变化检测方法不佳。
对于每个异步事件,将每个绑定(模型-Dom 绑定)与其旧值进行比较,以决定是否重新渲染。
-
NG1:>2500 名观察者,性能停滞不前
NG2:同样的问题仍然存在,但是您有一个很累人的解决方法:切换到不可变对象并将 ChangeDetectionStrategy.onPush 传播到您的应用程序中以关闭默认的有问题的策略
-
create-react-app 内部使用 Immutable.JS,而 Immutable.JS 在死前只能创建大约 500k 个不可变集合。
还有一些其他需要考虑的事情:
-
使用array.slice for manipulating arrays 来最小化额外的数组分配; array.slice 将修改数组,这将减少垃圾收集和整体堆大小。
【讨论】:
Chrome 警告您链接到的站点包含恶意软件。也许从网站上获取信息并直接复制到这里而不是提供链接? 自从 7 年前我最初写答案以来,我在去年重写了很多,环境发生了很大变化,例如 html5 和其他东西。【参考方案4】:Firefox 支持选项“javascript.options.mem.max”,如果您搜索该选项,您可以找到关于人们认为可行的合理值的讨论。
不确定有多少人会费心去设置它,但就我自己而言,我将它设置为 128000(即 128M)。
【讨论】:
我不是 Mozilla 专家,但 source/dom/base/nsJSEnvironment.cpp#2308 -> source/dom/base/nsJSEnvironment.cpp#2169 让我觉得单位是兆字节【参考方案5】:我认为内存限制来自浏览器。我们可以使用 DevTools 来解决这个问题。和chrome一样,按F12输入window.performance.memory就可以看到内存信息了。
window.performance.memory
【讨论】:
【参考方案6】:这可能因不同的网络浏览器而异,据观察,我使用 Chrome(版本 79.0.3945.130)选择了每个任务的最大值为 2Gb。 Chrome 调试器会在出现“在可能的内存不足崩溃之前暂停”消息时暂停网页。
但是,调试器确实允许恢复网页操作(通常会导致网页崩溃),但如果它不崩溃,则使用的内存可以攀升至 2Gb 以上,页面通常会在此之后执行更慢。似乎 2Gb 是基于每个任务设置的。
ie:我开发了一个基于 Web 的实时日志查看器,它显示日志信息,从一些本地日志文件中读取。可以请求查看日志文件的百分比。一些日志文件很大,可以包含 100 000 多行。当请求查看所有这些行时,Chrome 会崩溃,但如果我请求一次查看这些行 10 000 行,则完全没有问题。这让我得出“每个任务最大 2Gb”的结论。
这只是一个理论,我是正确的。参考附图
【讨论】:
以上是关于JavaScript 内存限制的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:堆限制附近的无效标记压缩分配失败 - JavaScript 堆内存不足 |反应
错误:接近堆限制的无效标记压缩分配失败 - JavaScript 堆内存不足
接近堆限制的无效标记压缩分配Angular 8 - JavaScript堆内存不足