你如何检测 JavaScript 中的内存限制?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23506064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you detect memory limits in JavaScript?
提问by
Can browsers enforce any sort of limit on the amount of data that can be stored in JavaScript objects? If so, is there any way to detect that limit?
浏览器是否可以对可以存储在 JavaScript 对象中的数据量施加任何限制?如果是这样,有什么方法可以检测到该限制吗?
It appears that by default, Firefox does not:
默认情况下,Firefox 似乎不会:
var data;
$("document").ready(function() {
data = [];
for(var i = 0; i < 100000000000; i++) {
data.push(Math.random());
}
});
That continues to consume more and more memory until my system runs out.
这会继续消耗越来越多的内存,直到我的系统耗尽为止。
Since we can't detect available memory, is there any other way to tell we are getting close to that limit?
由于我们无法检测到可用内存,有没有其他方法可以告诉我们正在接近该限制?
Update
更新
The application I'm developing relies on very fast response times to be usable (it's the core selling point). Unfortunately, it also has a very large data set (more than will fit into memory on weaker client machines). Performance can be greatly improved by preemptively loading data strategically (guessing what will be clicked). The fallback to loading the data from the server works when the guesses are incorrect, but the server round trip isn't ideal. Making use of every bit of memory I can makes the application as performant as possible.
我正在开发的应用程序依赖于非常快的响应时间才能使用(这是核心卖点)。不幸的是,它还有一个非常大的数据集(比弱客户端机器上的内存要大得多)。通过战略性地抢先加载数据(猜测将点击什么),可以大大提高性能。当猜测不正确时,从服务器加载数据的回退工作会起作用,但服务器往返并不理想。充分利用我可以使用的每一位内存,使应用程序尽可能提高性能。
Right now, it works to allow the user to "configure" their performance settings (max data settings), but users don't want to manage that. Also, since it's a web application, I have to handle users setting that per computer (since a powerful desktop has a lot more memory than an old iPhone). It's better if it just uses optimal settings for what is available on the systems. But guessing too high can cause problems on the client computer too.
现在,它允许用户“配置”他们的性能设置(最大数据设置),但用户不想管理它。此外,由于它是一个 Web 应用程序,我必须处理用户对每台计算机的设置(因为强大的桌面比旧的 iPhone 拥有更多的内存)。如果它只是对系统上可用的内容使用最佳设置,那就更好了。但是猜测太高也会导致客户端计算机出现问题。
采纳答案by Alex Pakka
While it might be possible on some browsers, the right approach should be to decide what limit is acceptable for the typical customer and optionally provide a UI to define their limit.
虽然在某些浏览器上可能可行,但正确的方法应该是确定典型客户可接受的限制,并可选择提供 UI 来定义他们的限制。
Most heavy web apps get away with about 10MB JavaScript heap size. There does not seem to be a guideline. But I would imagine consuming more than 100MB on desktop and 20MB on mobile is not really nice. For everything after that look into local storage, e.g. FileSystem API(and you can totally make it PERSISTENT)
大多数繁重的 Web 应用程序都会使用大约 10MB 的 JavaScript 堆大小。似乎没有指南。但我认为在桌面上消耗超过 100MB 并且在移动设备上消耗超过 20MB 并不是很好。之后查看本地存储的所有内容,例如FileSystem API(您可以完全使其持久化)
UPDATE
更新
The reasoning behind this answer is the following. It is next to never user runs only one application. More so with counting on the browser having only one tab open. Ultimately, consuming all available memory is never a good option. Hence determining the upper boundary is not necessary.
这个答案背后的原因如下。几乎从不用户只运行一个应用程序。指望只打开一个选项卡的浏览器更是如此。最终,消耗所有可用内存从来都不是一个好的选择。因此不需要确定上边界。
Reasonable amount of memory user would like to allocate to the web app is a guess work. E.g. highly interactive data analytics tool is quite possible in JS and might need millions of data points. One option is to default to less resolution (say, daily instead of each second measurements) or smaller window (one day vs. a decade of seconds). But as user keeps exploring the data set, more and more data will be needed, potentially crippling the underlying OS on the agent side.
用户希望分配给 Web 应用程序的合理数量的内存是一种猜测。例如,高度交互的数据分析工具在 JS 中是很有可能的,并且可能需要数百万个数据点。一种选择是默认较低的分辨率(例如,每天而不是每秒测量)或较小的窗口(一天与十年秒)。但随着用户不断探索数据集,将需要越来越多的数据,这可能会削弱代理端的底层操作系统。
Good solution is to go with some reasonable initial assumption. Let's open some popular web applications and go to dev tools - profiles - heap snapshots to take a look:
好的解决方案是采用一些合理的初始假设。我们打开一些流行的web应用,去开发工具-配置文件-堆快照看看:
- FB: 18.2 MB
- GMail: 33 MB
- Google+: 53.4 MB
- YouTube: 54 MB
- Bing Maps: 55 MB
- 脸书:18.2 MB
- GMail:33 MB
- Google+:53.4 MB
- YouTube:54 MB
- 必应地图:55 MB
Note: these numbers include DOM nodes and JS Objects on the heap.
注意:这些数字包括堆上的 DOM 节点和 JS 对象。
It seems to be then, people come to accept 50 MB of RAM for a useful web site. Once you build your DOM Tree, fill your data structures with test data and see how much is ok to keep in RAM.
似乎到那时,人们开始接受 50 MB 的 RAM 用于有用的网站。一旦你构建了你的 DOM 树,用测试数据填充你的数据结构,看看在 RAM 中保留多少是可以的。
Using similar measurements while turning device emulation in Chrome, one can see the consumption of the same sites on tablets and phones, BTW.
在 Chrome 中打开设备模拟时使用类似的测量,可以看到平板电脑和手机上相同站点的消耗,顺便说一句。
This is how I arrived at 100 MB on desktop and 20 MB on mobile numbers. Seemed to be reasonable too. Of course, for occasional heavy user it would be nice to have an option to bump max heap up to 2 GB.
这就是我在台式机上达到 100 MB 和在移动号码上达到 20 MB 的方式。似乎也很有道理。当然,对于偶尔的重度用户来说,可以选择将最大堆增加到 2 GB 会很好。
Now, what do you do if pumping all this data from the server every time is too costly?
现在,如果每次从服务器抽取所有这些数据的成本太高,你会怎么做?
One thing is to use Application Cache. It does create mild version management headaches but allows you to store around 5 MB of data. Rather than storing data though, it is more useful to keep app code and resources in it.
一件事是使用应用程序缓存。它确实会造成轻微的版本管理问题,但允许您存储大约 5 MB 的数据。与存储数据相比,将应用程序代码和资源保存在其中更有用。
Beyond that we have three choices:
除此之外,我们还有三个选择:
- SQLite - support was limited and it seems to be abandoned
- IndexDB - better option, but support is not universal yet (can I use it?)
- FileSystem API
Of them, FileSystem is most supported and can use sizeable chunk of storage
其中,FileSystem 受支持最多,可以使用相当大的存储块
回答by Benjamin Gruenbaum
In Chrome the answer is Sure!
在 Chrome 中,答案是肯定的!
Go to the console and type:
转到控制台并键入:
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
回答by Maxim Bernard
Since a web app can'thave access to any system-related information (like the available amount of memory), and since you would prefer not having to ask users to manually set their performance settings, you must rely on a solution that allows you to get such information about the user's system (available memory) without asking them. Seems impossible ? Well, almost...
由于 Web 应用程序无法访问任何与系统相关的信息(例如可用内存量),并且您不想让用户手动设置他们的性能设置,因此您必须依赖一种解决方案,允许您无需询问用户即可获取有关用户系统(可用内存)的此类信息。似乎不可能?嗯,差不多……
But I suggest you do the following : make a Java applet that will automatically get the available memory size (e.g. using Runtime.exec(...)
with an appropriate command), provided your applet is signed, and return that information to the server or directly to the web page (with JSObject, see http://docs.oracle.com/javafx/2/api/netscape/javascript/JSObject.html).
但我建议您执行以下操作:制作一个 Java 小程序,它会自动获取可用内存大小(例如使用Runtime.exec(...)
适当的命令),前提是您的小程序已签名,然后将该信息返回到服务器或直接返回到网页(使用JSObject,请参阅http://docs.oracle.com/javafx/2/api/netscape/javascript/JSObject.html)。
However, that would assume your users can all run a Java applet within their browsers, which is not always the case. Therefore, you could ask them to install a small piece of software on their machines that will measure how much memory your app should use without crashing the browser, and will send that information to your server. Of course, you would have to re-write that little program for every OS and architecture (Windows, Mac, Linux, iPhone, Android...), but it's simpler that having to re-write the whole application in order to gain some performance. It's a sort of in-between solution.
但是,这假设您的用户都可以在他们的浏览器中运行 Java 小程序,但情况并非总是如此。因此,您可以要求他们在他们的机器上安装一小块软件,该软件将测量您的应用程序应该使用多少内存而不会导致浏览器崩溃,并将该信息发送到您的服务器。当然,您必须为每个操作系统和体系结构(Windows、Mac、Linux、iPhone、Android...)重新编写那个小程序,但是为了获得一些好处而必须重新编写整个应用程序要简单得多。表现。这是一种介于两者之间的解决方案。
I don't think there is an easy solution. There willbe some drawbacks, whatever you choose to do. Remember that web applications don't have the reputation of being fast, so if performance is critical, you should consider writing a traditional desktop application.
我不认为有一个简单的解决方案。这里将是一些弊端,无论你选择做什么。请记住,Web 应用程序没有速度快的名声,因此如果性能至关重要,您应该考虑编写传统的桌面应用程序。