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

时间:2014-05-06 23:12:44

标签: javascript

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

默认情况下,Firefox似乎没有:

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

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

既然我们can't detect available memory,还有其他方法可以告诉我们接近这个限制吗?

更新

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

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

4 个答案:

答案 0 :(得分:33)

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

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

更新

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

用户想要分配给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最受支持,可以使用sizeable chunk of storage

答案 1 :(得分:31)

在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

答案 2 :(得分:2)

由于网络应用无法可以访问任何与系统相关的信息(例如可用的内存量),并且您不希望让用户手动设置在性能设置方面,您必须依赖于一种解决方案,该解决方案允许您在不询问用户的情况下获取有关用户系统(可用内存)的此类信息。似乎不可能?好吧,差不多......

但我建议您执行以下操作:创建一个Java applet,它将自动获取可用的内存大小(例如,使用Runtime.exec(...)和适当的命令),前提是您的applet已签名,并将该信息返回给服务器或直接访问网页(使用JSObject,请参阅http://docs.oracle.com/javafx/2/api/netscape/javascript/JSObject.html)。

但是,这会假设您的用户都可以在他们的浏览器中运行Java applet,但情况并非总是如此。因此,您可以要求他们在他们的计算机上安装一小块软件,这些软件将测量您的应用程序应该使用多少内存而不会崩溃浏览器,并将该信息发送到您的服务器。当然,你必须为每个操作系统和架构(Windows,Mac,Linux,iPhone,Android ......)重新编写这个小程序,但更简单的是必须重新编写整个应用程序。为了获得一些表现。它是一种中间解决方案。

我认为没有一个简单的解决方案。无论你选择做什么, 都会有一些缺点。请记住,Web应用程序不具备快速的声誉,因此如果性能至关重要,则应考虑编写传统的桌面应用程序。

答案 3 :(得分:2)

我想你会想要以下内容:

const memory = navigator.deviceMemory
console.log (`This device has at least ${memory}GiB of RAM.`)

您可以查看以下内容:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory

注意:并非所有浏览器都支持此功能。