New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 749482 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: Sep 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug



Sign in to add a comment

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'`
 
testCase
3.4 KB View Download

Comment 1 by hayato@chromium.org, Jul 27 2017

Components: -Blink>DOM Blink>Network>XHR

Comment 2 by be...@peer5.com, 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. 
meminfo.txt
15.5 KB View Download
Screen Shot 2017-07-27 at 14.27.15.png
91.7 KB View Download

Comment 3 by be...@peer5.com, Jul 27 2017

Confirmed this crashes on a real device (Nexus 5X). 

Comment 4 by rob.le...@gmail.com, 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()]);
})();
4fXDjyb.png
148 KB View Download

Comment 5 by ricea@chromium.org, Jul 27 2017

DevTools intentionally extends the lifetime of objects. Can you reproduce without DevTools open?

Comment 6 by be...@peer5.com, 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.

Comment 7 by be...@peer5.com, 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)
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.


rep1.png
133 KB View Download
rep2.png
20.9 KB View Download
Components: Mobile>WebView
Labels: Needs-Feedback
 benji@, can you please provide bugreport,logcat, chrome trace for the issue?

Comment 10 by be...@peer5.com, 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).
Project Member

Comment 11 by sheriffbot@chromium.org, Jul 30 2017

Cc: ppolise...@chromium.org
Labels: -Needs-Feedback
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
Labels: Needs-Feedback
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

Cc: yukishiino@chromium.org
Components: Blink>Bindings
Status: Available (was: Unconfirmed)
Reproduced on Linux.

Not reproducible when removing xhr.responseType = 'arraybuffer'.

yukishiino@, can you take a look?
Cc: etienneb@chromium.org

Comment 15 by be...@peer5.com, 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. 
Cc: haraken@chromium.org
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.

Cc: tyoshino@chromium.org
yoshino-san: Do you have any thoughts on this?

Owner: yukishiino@chromium.org
Status: Started (was: Available)
Project Member

Comment 19 by bugdroid1@chromium.org, 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

Status: Fixed (was: Started)

Sign in to add a comment