Bug 227636 - decodeAudioData crashes tab on iOS Safari
Summary: decodeAudioData crashes tab on iOS Safari
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Audio (show other bugs)
Version: Safari 14
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-07-02 13:11 PDT by chrisguttandin
Modified: 2021-07-31 01:07 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description chrisguttandin 2021-07-02 13:11:56 PDT
When decoding a lot of files in parallel with decodeAudioData() on an iOS device the tab crashes. The same code works on macOS Safari. It also works in any other browser I tested it with including some Android browsers.

https://1tdp1.csb.app/

The source code for this example is available here: https://codesandbox.io/s/stupefied-snowflake-1tdp1?file=/src/index.ts

Please let me know if you need any other information.
Comment 1 Chris Dumez 2021-07-02 13:20:39 PDT
I haven't tried reproducing yet but I suspect an iOS jetsam (memory kill due to memory usage for the process that is higher than what the system allows).
Comment 2 Chris Dumez 2021-07-02 13:32:14 PDT
(In reply to Chris Dumez from comment #1)
> I haven't tried reproducing yet but I suspect an iOS jetsam (memory kill due
> to memory usage for the process that is higher than what the system allows).

Yes, I can reproduce and see a Jetsam happening (over 1.5GB of memory used). I haven't looked at the example code yet to understand if such memory usage is expected or not (could be that WebKit is leaking stuff for example). We cannot use that much memory on iOS without getting killed.
Comment 3 chrisguttandin 2021-07-02 13:37:45 PDT
Thanks for taking a look at this Chris. Is there a way to know the allowed maximum memory from within the browser? It would, of course, be possible to stagger the calls to decodeAudioData() when knowing the limit is reached.

During my tests I noticed that directly running decodeAudioData() again after the promise return from the previous call resolved didn't work. I experimentally came up with a gap of 100ms between each call which seems to work.

I also noticed that the maximum number seems to be different on an iPhone and on an iPad.
Comment 4 Chris Dumez 2021-07-02 13:47:24 PDT
(In reply to chrisguttandin from comment #3)
> Thanks for taking a look at this Chris. Is there a way to know the allowed
> maximum memory from within the browser? It would, of course, be possible to
> stagger the calls to decodeAudioData() when knowing the limit is reached.
> 
> During my tests I noticed that directly running decodeAudioData() again
> after the promise return from the previous call resolved didn't work. I
> experimentally came up with a gap of 100ms between each call which seems to
> work.
> 
> I also noticed that the maximum number seems to be different on an iPhone
> and on an iPad.

Sadly, there is not really a way to know from JS. When the system is under memory pressure (or determines that a particular process is above its allowed threshold), it sends WebKit a memory pressure warning and WebKit does its best to free up memory (this includes triggering JavaScript garbage collection). However, this signal/warning is not currently exposed to JS. I am also unaware of any Web API that would give you the amount of free memory.
Comment 5 chrisguttandin 2021-07-03 09:42:35 PDT
Would it be possible to schedule the decoding operations internally to make sure WebKit does not reach the memory limit?
Comment 6 Radar WebKit Bug Importer 2021-07-09 13:12:16 PDT
<rdar://problem/80391006>