[Problem/Bug]: OutOfMemory exception when writing response in WebResourceRequest
What happened?
My application uses WebResourceRequest interception to provide data from a local file to WebView2. We still build an x86 variant and we experience OutOfMemory-Crashes in EmbeddedBrowserWebView.dll when writing a larger response (~120MB). In the x64 build we don't run into that problem.
The API suggests that the response data is streamed to the WebView2 process but it seems that the data is collected before sending which leads to huge memory allocations and then finally to the OutOfMemory situation.
Importance
Important. My app's user experience is significantly compromised.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
120.0.2210.61
SDK Version
1.0.2194.0
Framework
Win32
Operating System
Windows 10
OS Version
19045.3803
Repro steps
I used the WebView2Samples repo to reproduce the bug:
- Clone
WebView2Samplesrepo - Modify the file
SampleApps\WebView2APISample\assets\ScenarioCustomScheme.htmlso that it's size is larger than 200MB (e. g. by adding a comment which is 200MB in size) - Switch to
x86and build theWebView2APISampleapp in Release-Mode - Run the app
- Select "Scenario / Navigate to custom scheme via WebResourceRequested"
- App crashes with this callstack:
EmbeddedBrowserWebView.dll!partition_alloc::internal::OnNoMemoryInternal() Unknown Symbols loaded.
EmbeddedBrowserWebView.dll!partition_alloc::TerminateBecauseOutOfMemory(unsigned int) Unknown Symbols loaded.
EmbeddedBrowserWebView.dll!partition_alloc::internal::OnNoMemory(unsigned int) Unknown Symbols loaded.
EmbeddedBrowserWebView.dll!partition_alloc::PartitionRoot::OutOfMemory(unsigned int) Unknown Symbols loaded.
...
When running that with the VS-Memory-Profiler I can see that the private bytes peak at 1.1GB before crashing.
What I would derive from that:
- the response data isn't really streamed but collected before sending to the WV2 process, otherwise the memory consumption would be rather flat
- there are unfortunate reallocations happening that bring the memory usage up to over 1GB which is quite heavy for a 200MB response
- when I profile the
x64variant the memory peaks at 1.6GB (!) before dropping down. That's ~8 times the size of the response data
Repros in Edge Browser
No
Regression
No, this never worked
Last working version (if regression)
No response
@Urmeli0815 For x86 app, can you ensure that you have LargeAddressAware set when building the app and see that resolves the issue.
@monica-ch While this mitigates the problem (it crashes then with a ~400MB file with ~2.6GB of memory allocated) I think this can't be regarded as a solution. I think there is an issue with the way the data is forwarded via IPC from the host process to the WV2 process.
I would have expected that the data (~400MB) is at most copied once and then handled within the host process without further memory allocations (that would mean ~800MB memory allocation maximum). But with the x64 build the max. allocated memory is ~3.1GB which is ca. 8 times the size of the original file (400MB). This looks inefficient for me as there are too many memory allocations, probably including duplication of data.
While this results in a crash in this scenario I would assume that this affects every WebResourceRequested usage as data is copied multiple times during processing the request. This looks like an opportunity to optimize the handling of WebResourceRequests.
Any updates on this issue? We experience more and more OutOfMemory crashes of our app (also with x64 now), and all happens in EmbeddedBrowserWebView.dll.
The irony is that the nearly same web content doesn't crash with OutOfMemory when we use Edge! So it would be very much appreciated if you could help us to circumvent this problem. What could help if you could explain internal details about how the response data is handled in EmbeddedBrowserWebView.dll, so that we might change/optimize the API calls on our side.