【问题标题】:How to catch and handle Chrome memory crash?如何捕捉和处理 Chrome 内存崩溃?
【发布时间】:2017-11-15 19:32:09
【问题描述】:

我在AudioBuffer 中加载了两个 300MB MP3 文件,然后继续将它们编码为 WAV 文件。在编码过程中的某个地方(发生在 web worker 中),浏览器由于内存不足而崩溃。

WAV 文件大约是 MP3 文件的 3 倍,因此需要大约 1.8GB 的​​额外空间来进行转换。

文件可以是任意大小,因为它们是用户选择上传的 mp3 文件,所以它们可以是 10MB 或 350MB。这意味着内存可能不够,也可能不够。如果还不够,我该如何简单地捕获并处理错误而不是让浏览器崩溃?

我会将用户限制为特定项目(所有文件组合)的大小,但似乎最大内存限制因操作系统、操作系统架构、浏览器版本和浏览器架构而异,这使得几乎不可能定义这样的限制。

【问题讨论】:

    标签: google-chrome memory v8


    【解决方案1】:

    很遗憾,没有办法“捕获并处理”内存不足错误,抱歉。按照设计,出于安全原因,V8 总是在进程无法分配所需内存时崩溃。

    JavaScript 堆的内存限制是根据机器拥有的物理内存量动态确定的。几年来,在“足够”内存的情况下,32 位桌面架构为 700 MB,64 位架构为 1400 MB;但是最近版本的 Chrome/V8 一直在调整策略,现在 64 位的上限是 2048MB。所以是的,细节会随着时间而改变。不过,操作系统并不重要(至少对于 JavaScript 堆而言)。

    我不完全确定 AudioBuffers 是否计入 V8 的堆限制(V8 本身不知道 AudioBuffers,它们是由嵌入器实现的,即 Blink)。

    请注意,您可能无法使用每个最后一个字节达到该最大值。一些内存用于内部元数据;并且当您动态地增长数组等时,它们会以块的形式增长,这使得即使增长前的大小不是“最大减一”,增长的尝试也可能达到极限。在 32 位平台上,尝试分配单个大对象也可能由于地址空间耗尽而失败:在为这个和那个分配了许多随机选择的页面之后,在进程的生命周期内,可能根本就没有足够的可用于分配数百兆大对象的大块连续地址空间,即使尚未达到堆限制。

    旁注:“大三倍”?对于常用的 MP3 比特率,我希望 WAV 文件最大 10 倍。

    【讨论】:

    • 这个答案 (stackoverflow.com/a/34667584/5086286) 表明操作系统和浏览器版本对内存限制有影响,尽管他可能是在谈论整个选项卡内存,而您是在专门谈论 JS 堆尺寸。我认为AudioBuffers 包含在 V8 的堆中,就像我拍摄“堆快照”时一样。至于 WAV 编码,我正在转换为 16 位文件,这可以解释为什么它只有 3-4 倍大。我将测试 JS 堆限制,我会回复您。非常感谢您的帮助!
    • 我目前有一个工作页面,其 JS 堆大小为 1503MB(根据堆快照),这让我相信 1400MB 不是限制。
    • 嗯,好点子。在 Chrome M56 之前,限制是 1400 MB,而 M57 将其提升到 2048 MB。我会更新我的答案。
    • 您知道我在哪里可以找到有关此信息的官方文档吗?
    • 仅在源代码中:chromium.googlesource.com/v8/v8/+/master(查看src/heap/heap.h)。 FWIW,大多数内存不足崩溃发生在操作系统用完实际内存时,无论 V8 的内部限制如何。
    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多