Making an XHR with responseType="arraybuffer" leaks memory
Reported by
be...@peer5.com,
Jul 27 2017
|
||||||||||
Issue description
Steps to reproduce the problem:
1. Create a WebView in Android, add it to the screen
2. Go to its devtools (from about:inspect)
3. Paste the following code
function req() {
return new Promise(resolve => {
var xhr = new XMLHttpRequest;
xhr.open("GET", "https://example.com/someFiveMegabyteFile.test?foo="+Date.now());
xhr.onload = resolve;
xhr.responseType = 'arraybuffer';
xhr.send();
});
}
(async () => {
while(true) await req();
})();
4. Wait.
What is the expected behavior?
Chrome should not crash.
What went wrong?
Chrome crashed and the app exited.
Did this work before? N/A
Does this work in other browsers? N/A
Chrome version: 58.0.3071.115 Channel: n/a
OS Version: 7.0.0 (Emulator)
Flash Version:
This does not reproduce if we don't set `responseType='arraybuffer'`
,
Jul 27 2017
Update, tested in regular Chrome on Android, this bug reproduces in regular mobile chrome (Chrome (58.0.3029.121)) in the emulator (although after much longer - about 10 minutes). With the same code.
,
Jul 27 2017
Confirmed this crashes on a real device (Nexus 5X).
,
Jul 27 2017
tested on Chrome 58.0.3029.81, Linux, 64-bit.
crashed the tab after roughly 10-15 minutes. Memory never exceeded ~200mb for that tab.
Code:
function req() {
return new Promise(resolve => {
var xhr = new XMLHttpRequest;
xhr.open("GET", "path/to/100mb.testfile?foo="+Date.now());
xhr.onload = resolve;
xhr.responseType = 'arraybuffer';
xhr.send();
});
}
(async () => {
while(true) await Promise.all([req(), req(), req(), req(), req()]);
})();
,
Jul 27 2017
DevTools intentionally extends the lifetime of objects. Can you reproduce without DevTools open?
,
Jul 27 2017
In all my examples I've closed the devtools immediately after executing the JavaScript. I did however have the devtools open (initially) in order to paste that code. Let me know if you're interested in me testing this with a <script> tag instead of pasting the code in the devtools and I'll try it out.
,
Jul 27 2017
Reproduced this with the following callback code to rule out an issue with promise scoping:
function req(cb) {
var xhr = new XMLHttpRequest;
xhr.open("GET", "https://example.com/test5m.test?foo="+Date.now());
xhr.onload = cb;
xhr.responseType = 'arraybuffer';
xhr.send();
}
function pump() {
var i = 0;
req(() => (++i === 5) && pump());
req(() => (++i === 5) && pump());
req(() => (++i === 5) && pump());
req(() => (++i === 5) && pump());
req(() => (++i === 5) && pump());
}
pump()
```
(console was closed, and it was loaded as a data URI)
,
Jul 28 2017
Chrome 59.0.3071.115 (Official Build) (64-bit) on Ubuntu 16.04 here. It takes a while to crash, several hours, while going very high sometimes in memory.
,
Jul 28 2017
benji@, can you please provide bugreport,logcat, chrome trace for the issue?
,
Jul 30 2017
Hey, thanks for the response, I'll try to create a self-isolated app that demonstrates this on GitHub. I'll then run it and provide the logcat and chrome trace (not sure how to get a "bugreport", help appreciated).
,
Jul 30 2017
Thank you for providing more feedback. Adding requester "ppolisetty@chromium.org" to the cc list and removing "Needs-Feedback" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jul 31 2017
Thanks. To get bugreport: Android Settings > About Phone > Tap Build number 7 times, go back one screen, Developer options should be right above About phone. Once you have enabled developer options, to take a bug report,go to Android Settings -> Developer Options ->Enable USB Debugging and then tap on Take bug report
,
Aug 10 2017
Reproduced on Linux. Not reproducible when removing xhr.responseType = 'arraybuffer'. yukishiino@, can you take a look?
,
Aug 15 2017
,
Aug 15 2017
Hey, sorry, I noticed you reproduced this already and I don't have access to an Android device I can reproduce this on. I think this is easier to fix in Desktop anyway and you have already reproduced this. If you'd like I can get a bugreport, logcat and meminfo log next week.
,
Aug 31 2017
As far as I investigated, this seems a problem of blink::XMLHttpRequest. DOMArrayBuffer seems working fine. blink::XHR internally holds |binary_response_builder_| and |blob_loader_|, and they're consuming memory or disk, but V8 doesn't recognize it because they're not V8 objects. They're not DOMArrayBuffer, neither. Off the top of my head, there are two solutions at least (probably more). a) Make blink::XHR report the memory usage to V8. b) Make blink::SharedBuffer report the memory usage to V8. |blink::XHR::binary_response_builder_| is a SharedBuffer, however, SharedBuffer doesn't report any memory usage unlike ArrayBufferContents::DataHolder. Probably we should make SharedBuffer report the memory usage to V8 as same as ArrayBufferContents::DataHolder.
,
Aug 31 2017
yoshino-san: Do you have any thoughts on this?
,
Sep 5 2017
,
Sep 6 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/1a2e43bc1286101766edbff4dd59ac97b949cf4c commit 1a2e43bc1286101766edbff4dd59ac97b949cf4c Author: Yuki Shiino <yukishiino@chromium.org> Date: Wed Sep 06 09:23:29 2017 v8binding: Make XHR report its memory usage to V8. XHR currently does not report the memory usage of its |binary_response_builder_| and the disk usage of the downloaded blob to V8, so V8 cannot schedule GC and Blink run out memory. This CL makes XHR report the memory and disk usage to V8 appropriately. Bug: 749482 Change-Id: If2075ee9386b64a806172adef53adf0b36dafcde Reviewed-on: https://chromium-review.googlesource.com/650171 Commit-Queue: Yuki Shiino <yukishiino@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Cr-Commit-Position: refs/heads/master@{#499918} [modify] https://crrev.com/1a2e43bc1286101766edbff4dd59ac97b949cf4c/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp [modify] https://crrev.com/1a2e43bc1286101766edbff4dd59ac97b949cf4c/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.h
,
Sep 7 2017
|
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by hayato@chromium.org
, Jul 27 2017