你如何检测JavaScript中的内存限制?

47 javascript

浏览器是否可以对可以存储在JavaScript对象中的数据量实施任何限制?如果是这样,有没有办法检测到这个限制?

看来默认情况下,Firefox不会:

var data;
$("document").ready(function() {
  data = [];
  for(var i = 0; i < 100000000000; i++) {
    data.push(Math.random());
  }
});
Run Code Online (Sandbox Code Playgroud)

在我的系统耗尽之前,这会继续消耗越来越多的内存.

由于我们无法检测可用内存,有没有其他方法可以告诉我们接近这个限制?

更新

我正在开发的应用程序依赖于非常快的响应时间可用(它是核心卖点).不幸的是,它也有一个非常大的数据集(在较弱的客户端机器上将超过内存).通过战略性地预先加载数据(猜测将被点击的内容),可以大大提高性能.当猜测不正确时,从服务器加载数据的后退工作正常,但服务器往返不理想.利用每一点内存,我可以使应用程序尽可能高效.

现在,它可以让用户"配置"他们的性能设置(最大数据设置),但用户不想管理它.此外,由于它是一个Web应用程序,我必须处理每台计算机的用户设置(因为强大的桌面比旧的iPhone有更多的内存).如果它只是对系统上可用的设置使用最佳设置,那就更好了.但是猜太高也会导致客户端计算机出现问题.

Ale*_*kka 36

虽然在某些浏览器上可能是可能的,但正确的方法应该是确定典型客户可接受的限制,并可选择提供UI来定义其限制.

大多数重型网络应用程序都可以获得大约10MB的JavaScript堆大小.似乎没有指南.但我想在台式机上消耗超过100MB,在移动设备上消耗20MB并不是很好.对于之后的所有内容,请查看本地存储,例如FileSystem API(您可以完全使其成为PERSISTENT)

UPDATE

这个答案背后的原因如下.它永远不会让用户只运行一个应用程序.更重要的是依靠浏览器只打开一个标签.最终,消耗所有可用内存永远不是一个好选择.因此,确定上边界不是必需的.

用户希望分配给Web应用程序的合理内存量是猜测工作.例如,高度交互式数据分析工具在JS中非常有用,可能需要数百万个数据点.一种选择是默认为较低的分辨率(例如,每天而不是每秒测量)或较小的窗口(一天与十几秒).但随着用户不断探索数据集,将需要越来越多的数据,这可能会削弱代理端的底层操作系统.

好的解决方案是采用一些合理的初始假设.让我们打开一些流行的Web应用程序并转到开发工具 - 配置文件 - 堆快照来看看:

  • FB:18.2 MB
  • GMail:33 MB
  • Google+:53.4 MB
  • YouTube:54 MB
  • Bing地图:55 MB

注意:这些数字包括堆上的DOM节点和JS对象.

似乎是时候,人们开始接受50 MB的RAM用于有用的网站.构建DOM树后,使用测试数据填充数据结构,并查看可以保留在RAM中的数量.

在Chrome中转换设备模拟时使用类似的测量,可以看到平板电脑和手机上相同网站的消耗,BTW.

这就是我在台式机上达到100 MB,在手机号码上达到20 MB的方式.似乎也是合理的.当然,对于偶尔的重度用户来说,最好有一个选项可以将最大堆数增加到2 GB.

现在,如果每次从服务器中提取所有这些数据太昂贵,你会怎么做?

一件事是使用Application Cache.它确实会产生温和的版本管理难题,但允许您存储大约5 MB的数据.不是存储数据,而是将应用程序代码和资源保留在其中更有用.

除此之外,我们有三个选择:

其中,FileSystem最受支持,可以使用相当大的存储空间

  • +1 表示“*消耗所有可用内存从来都不是一个好的选择*” (2认同)
  • 在facebook上滚动将内存从13.7MB增加到30MB.在Pinterest上滚动一分钟左右,内存增加到70MB,但是它们有很多图像. (2认同)

Ben*_*aum 32

在Chrome中答案是肯定的!

转到控制台并键入:

performance.memory.jsHeapSizeLimit; // will give you the JS heap size
performance.memory.usedJSHeapSize; // how much you're currently using

arr = []; for(var i = 0; i < 100000; i++) arr.push(i);
performance.memory.usedJSHeapSize; // likely a larger number now
Run Code Online (Sandbox Code Playgroud)

  • @RobW我喜欢告诉你是的,因为我认为将来没有理由将其删除(而且Chrome用户会使用它)但是老实说 - 我不知道.一旦我学会了如何编写更快的JS(避免闭包,内联所有内容,单态函数,位掩码,回收属性),我从未达到客户端代码中的性能限制,这种方式迫使我进行功能检测_memory_(功能检测cpu加载是一个更可行和更简单).我问过我熟悉的相关人员,希望我最终能得到答案. (3认同)
  • 现在是 2017 年,我需要通过 JavaScript 网页传递数十 GB 的内存 - 而 Chrome 在达到内存限制之前会崩溃 - 会因回调而终止。 (2认同)