3

使用 Google Chrome,假设我使用 ajax 将文件下载为 blob,如下所示:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'some/path', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {      
    //Save xhr.response using FileSystem API
};

xhr.send();

我是否需要担心这里的内存使用(假设下载的文件可能非常大,或者我可能会以这种方式下载大量文件)?

我的理解是,由于我将 responseType 指定为“blob”而不是“arraybuffer”,因此下载的数据不会加载到 Javascript 可用的内存中。但是,下载的数据必须存储在某个地方。它只是存储在内存中,还是浏览器会在必要时将其放入某种内存不足的缓存中?如果它被保存在内存中,有什么方法可以让我在完成后处理它(即,在我的示例中,一旦我使用 FileSystem API 保存它)。

4

4 回答 4

1

对于二进制或 blob 数据,Chrome 使用一个复杂的系统,该系统由一个用于选项卡的内存缓冲区和一个异步全局存储逻辑组成,该逻辑还将数据交换到磁盘。选项卡内存、全局存储容量以及重要的数据在两者之间传输和换出的速度都有限制。

这与保存您的代码和常规变量的可用 JavaScript 内存不同。

无法确切知道这些限制是什么,但创建 blob 的速度起着至关重要的作用。将这些操作减慢到,比如慢磁盘的速度,可以大大增加应用程序的可用内存。

可以在此处找到有关 Chrome 的 Blob 存储的说明: https ://chromium.googlesource.com/chromium/src/+/master/storage/browser/blob/README.md

回答你的问题:是的,你需要担心那里的记忆。如果您在 XHR 请求中一次性加载的数据大于可用的选项卡内存,则选项卡将崩溃。同样,如果您随着时间的推移超出全局存储限额或加载许多较小的文件太快,您也会遇到问题。

于 2019-08-07T15:40:09.740 回答
0

我想它也会进入记忆。我记得一些关于 chrome 能够在某个地方处理 800 MB 内存的事情,不确定。

但我对约 1 GB 的电影进行了测试,并查看了网络选项卡。最正确的是,当我看到 ~760 MB 基准时它崩溃了。所以你最好的选择是请求块并将其附加到文件系统

于 2014-02-18T15:56:34.800 回答
0

我无法回答您关于数据存储位置的具体问题,但我想它会存储在磁盘上的内存中。

不过,我可以回答的部分是如何释放 blob 对象本身使用的内存(不一定是数据,只是 blob 对象)。只要您不在当前范围内使用对象或范围已结束,它将自动被清理。例如,在闭包或匿名函数中,当函数结束时,在该范围内创建的任何内容都将被垃圾回收。您也可以手动将其分配给 null 或调用 delete。

您应该从 MDN阅读有关删除运算符的信息。MDN 上还有一个内存管理页面,它更详细地解释了上述过程。

于 2013-07-29T21:09:31.057 回答
0

数据始终存储在 nsCString 内的内存中,该 nsCString 通过加倍动态增长。因此,一个 260 MB 的文件最多可保留约 512 MB 的内存。如果要将响应数据复制到 arraybuffer 中,内存峰值会增加到 772 MB,因为还需要分配 arraybuffer (260MB)。

只要 XHR 对象存在,临时 512 MB nsCString 就会被保留。所以你必须设置 xhr=null,垃圾收集和释放内存。当然,许多移动系统没有太多可用内存,并且可能由于“内存不足”而崩溃。某些浏览器版本的每个选项卡都有内存限制,并且已经在 768MB 内存使用时崩溃。

那里有一个新的Fetch-API,它允许基于块的读取。流式传输响应主体可提高内存使用率。在 XHR 中,整个响应将被缓冲,而不是能够对数据块进行操作。

于 2017-01-18T15:00:21.183 回答