0

I'm loading two 300MB MP3 files in an AudioBuffer and then proceed to encode them as WAV files. Somewhere along the process of encoding (which happens in a web worker), the browser crashes because of a lack of memory.

Chrome crash

WAV files are about 3 times larger than MP3 files, so it would need ~1.8GB additional space to do the conversion.

The files can have any size, because they are mp3 files that the user chose to upload, so they can be 10MB or 350MB. This means that the memory may or may not be sufficient. In case that it isn't sufficient, how do I simply catch and handle the error instead of having the browser crash?

I would limit the user to a specific project (all files combined) size, but it seems like the maximum memory limit varies with the OS, OS architecture, browser version and browser architecture which makes it almost impossible to define such limit.

Maxime Dupré
  • 5,319
  • 7
  • 38
  • 72

1 Answers1

3

Unfortunately there is no way to "catch and handle" an out-of-memory error, sorry. By design, for security reasons, V8 always crashes the process when it cannot allocate memory it needs.

The memory limit for the JavaScript heap is determined dynamically based on the amount of physical memory that the machine has. For several years, given "sufficient" RAM, it was 700 MB on 32-bit desktop architectures and 1400 MB on 64-bit architectures; however recent versions of Chrome/V8 have been tuning the strategy and the upper limit is now 2048MB on 64-bit. So yes, the specifics can change over time. The OS does not matter, though (at least not for the JavaScript heap).

I'm not entirely sure whether AudioBuffers count towards V8's heap limit (V8 itself doesn't know about AudioBuffers, they're implemented by the embedder, i.e. Blink).

Note that you may not be able to use every last byte up to that maximum. Some memory is used for internal metadata; and when you grow arrays and the like dynamically, they grow in chunks, which makes it likely that an attempt to grow hits the limit even though the pre-growth size was not "maximum minus one". On 32-bit platforms, trying to allocate a single large object can also fail due to address space exhaustion: after a number of randomly selected pages have been allocated for this and that over the lifetime of the process, there might simply not be a sufficiently large contiguous block of address space available to allocate a several-hundred-megabytes large object, even if the heap limit isn't reached yet.

Side note: "three times larger"? For commonly used MP3 bitrates, I'd expect WAV files to be up to 10 times larger.

jmrk
  • 34,271
  • 7
  • 59
  • 74
  • This answer (https://stackoverflow.com/a/34667584/5086286) suggests that the OS and browser version have an effect on the memory limit, although he might be talking of the entire tab memory, whereas you are talking specifically about the JS heap size. I think that the `AudioBuffers` are included in the V8's heap, as when I take a "Heap snapshot" it is included. As for the WAV encoding, I'm converting to a 16-bit file, which might explain why it's only 3-4 times larger. I'll test the JS heap limit and I'll get back to you. Thanks a lot for your help! – Maxime Dupré Jun 13 '17 at 21:54
  • I currently have a working page that has a JS heap size of 1503MB (according to a heap snapshot), which makes me believe that 1400MB isn't the limit. – Maxime Dupré Jun 13 '17 at 22:06
  • Huh, good point. Turns out the limit was 1400 MB until Chrome M56, and M57 bumped it to 2048 MB. I'll update my answer. – jmrk Jun 14 '17 at 08:40
  • Do you know where I can find the official documentation regarding this information? – Maxime Dupré Jun 14 '17 at 15:12
  • Only in the source code: https://chromium.googlesource.com/v8/v8/+/master (look in `src/heap/heap.h`). FWIW, most out-of-memory crashes happen when the operating system runs out of actual memory, regardless of V8's internal limits. – jmrk Jun 14 '17 at 15:25