【发布时间】:2019-03-12 18:52:37
【问题描述】:
当以最简单的方式使用 fetch-API 时,Chrome 无法正确收集垃圾。我做错了吗?
for (i = 0; i < 100; i++) {
fetch('https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg')
.then(response => {
console.log('Memory-bloating')
})
}
https://jsfiddle.net/dozrpcvj/12/
这个 JSFiddle 用 1.4GB 填充内存,直到您手动进行垃圾收集或关闭选项卡后才会释放。如果将迭代次数增加到 1000 次,它会“下载”14GB(从自己的磁盘),而不是垃圾收集,而是开始填充磁盘上的交换文件。
是我做错了什么还是 Chrome 中的错误?使用 Safari 进行测试时,它也会用 1.4GB 填充硬盘驱动器,但一旦完成就会开始垃圾收集。
PS。您不能使用内存分析器,因为它告诉您您只使用了几 MB 的数据,即使活动监视器或 Chrome 自己的任务管理器显示 1.4GB。
【问题讨论】:
-
有趣的注释 - 我似乎无法在开发工具中找到该内存。拍摄内存快照报告约 10 兆,查看性能选项卡,它不会报告异常的内存使用 - 从约 8 兆到最多约 16,在加载期间。任务管理器确实显示了超过 1.5 gig 的已用内存,并且我打开了一个 Chrome 选项卡。在性能选项卡上点击记录,然后进行垃圾回收会释放大约一兆的 JS 堆内存(11MB -> 10MB),但任务管理器报告至少释放了一个内存。
-
@vlaz 是的,这也是我注意到的。我已经通过 Chrome 向 Google 报告了它,但我想知道是我使用了错误的方式获取,还是 Chrome 处理了错误的方式。
-
不管怎样,我在 Firefox 中得到了类似的结果。有时。 JSFiddle 将我的内存使用量从 1.2GB 增加到 ~3.3GB,但随后它就清理干净了。但是,在控制台中执行相同的代码会达到 2.7GB 左右,并且会在此停留一段时间,然后才会自行清理。看起来 GC 有时会稍后启动。有时我似乎与 Chrome 有类似的结果:打开新选项卡 -> 在控制台中运行代码。 第一次我这样做,它达到〜1.6GB,然后又回到〜250MB。 第二次 我在同一个选项卡中执行此操作(不重新加载),内存保持高位。
-
我尝试了很多方法,包括将 null 设置为变量、调整数组大小和手动触发 GC。最后,我已经解决了刷新页面。这会立即降低内存使用量,但会导致延迟,直到我可以在浏览器中执行更多 javascript。
-
Chrome 正在尽其所能,您没有做错任何事。内存的分配是设计使然。 Chrome 会自动每隔一段时间收集垃圾,然后内存将再次被释放。由您(如果您按下检查器内的回收站)或automatically in ("unknown") intervals。如果您将每个响应引用存储在(例如)
window["fetch-n"]中,则内存分配将在垃圾回收后保留。
标签: javascript google-chrome memory-leaks fetch fetch-api