Issue metadata
Sign in to add a comment
|
Memory leak when using string functions in XHR event handler (and some workaround)
Reported by
briz...@gmail.com,
Mar 15 2018
|
||||||||||||||||||||||||
Issue description
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36
Steps to reproduce the problem:
1. Open any site with available big file to avoid CORS issues (only to show bug obviously)
2. Open Developer console and enter following code:
var st=[],NN=100,myval=16; //or st=""
var xh = new XMLHttpRequest();
xh.onload=function()
{
var txt=this.responseText;
var iii=txt.indexOf("SOMETEXT"); // put here substring contained in file
st[NN]=txt.substr(iii,myval); //or st+=txt.substr(iii,myval);
console.log("done");
}
console.log("go"); NN--; xh.open("GET","http://some.url/bigfile?"+Math.random()); xh.send();
3. Iterate last line some times by any manner (hands, events, timers etc) and take memory snapshot, or even wait up to page fails (how long is depends on file size and your RAM).
3.1. Set myval to values less than 12 to fix the problem. Set again to larger than 12 to continue heap growing.
3.2. Value of NN is for example only, you may set it any positive or even remove array and use concatenation (st+=txt.substr(...))
What is the expected behavior?
Execution without memory leaks with any myval values, if indexOf finds substring.
What went wrong?
When substring is found, memory leak rises if myval > 12.
Did this work before? N/A
Chrome version: 65.0.3325.146 Channel: n/a
OS Version: 10.0
Flash Version:
Tested on:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Issue revealed during implementation of some code with large amount of XHR queries in, to find substrings in server responses. To avoid memory leak in production code I now take full substring (which is much longer than 12 bytes) by 12-byte chunks.
,
Mar 16 2018
Interesting. My guess would be that substrings are implemented as references into the longer string, and so keep it alive. Sending to Blink>MemoryAllocator>GarbageCollection component for confirmation.
,
Mar 20 2018
@brizala: Could you please share a sample test file/URL which helps us to triage the issue further, as we are not very sure about any site with a big file which avoids CORS issues. Any further inputs from your end may help us. Thanks!
,
Mar 20 2018
2vamshi.kommuri: OK, try it: 1. go to https://ocw.mit.edu/ and open console 2. let set searching word as "twelve" in code above 3. set file parameter as "https://ocw.mit.edu/ans7870/6/6.006/s08/lecturenotes/files/t8.shakespeare.txt" (about 5 Mb) 4. now play few times with iterations, value of myval, and heap snapshoting - so looking at Summary/(string) reveals the number of identical (in this showcase) strings growing if myval > 12. PS Possibly ricea@ was right (Comment2), it seems your substring implementation hauls an unneeded original string internally.
,
Mar 20 2018
Thank you for providing more feedback. Adding the requester to the cc list. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 27 2018
cc +yukishiino who knows something about garbage collection. Can you confirm my guess in #2?
,
Mar 27 2018
Adam(ricea)'s guess seems correct to me. https://cs.chromium.org/chromium/src/v8/src/factory.cc?rcl=2943c641a94a3b5e5847f3549af11a8df03cd8cd&l=866 where V8 seems creating a SlicedString that has a reference to the parent string if the substring length is not less than SlicedString::kMinLength (= 13). Adam(adamk), would you triage this issue? This seems like a V8 issue to me.
,
Mar 27 2018
Indeed this is due to V8, though the code in question is not the factory but the CodeStubAssembler in this case: https://cs.chromium.org/chromium/src/v8/src/code-stub-assembler.cc?rcl=2943c641a94a3b5e5847f3549af11a8df03cd8cd&l=5038 Marking as a V8 Runtime issue and assigning to verwaest@ for further triage, though in some sense this is "working as intended".
,
Mar 28 2018
Re-assigning to ishell for possibly-faster response.
,
Mar 29 2018
Indeed, sliced strings keep their "parent" alive. This is unfortunate, but difficult to solve.
For the record, this is not at all specific to XHR responses, a repro is as simple as:
var long_lived = (function() {
var huge_string = (new Array(1000000)).join("x");
return huge_string.substr(1, 20);
})();
And "huge_string" will stay alive as long as "long_lived" is around.
|
|||||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||||
Comment 1 by viswa.karala@chromium.org
, Mar 15 2018