Creating sequence of ImageBitmaps in worker exhausts memory
Reported by
martin.v...@gmail.com,
Mar 27 2017
|
||||||||
Issue descriptionUserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0 Steps to reproduce the problem: 1. Have a worker thread crate a sequence of images using createImageBitmap, posting each to the main thread once it is ready. 2. Have the main thread keep the latest such image and use it for rendering. Run the HTML file from the attached ZIP to see this. What is the expected behavior? Only one image kept in main thread, so GC should collect the others and memory consumption should be constant. What went wrong? Memory consumption keeps rising. Tab gets killed at about 1.5G of memory on my system. System crashes reported by others. Did this work before? N/A Chrome version: 57.0.2987.54 (Developer Build) (64-bit) Channel: n/a OS Version: 4.9.9 Flash Version: Shockwave Flash 24.0 r0 I THINK this used to work better in previous versions, around Chromium version 54 or so, but I'm not sure. https://github.com/CindyJS/CindyJS/pull/517#issuecomment-289402683 is the context where we encountered this. Firefox had a similar problem, see https://bugzilla.mozilla.org/show_bug.cgi?id=1312148 for discussion. There the memory consumption was not tracked so the memory pressure was not detected and the garbage collector not executed.
,
Mar 28 2017
The given example file gives a DOM exception. I'm not sure how to fix that, maybe turn off security checks locally. But in any case, the worker is using canvas.
Uncaught DOMException: Failed to construct 'Worker': Script at 'file:///Users/schenney/Downloads/Stickler2/ifs.js' cannot be accessed from origin 'null'.
at file:///Users/schenney/Downloads/Stickler2/Stickler2.html:5:20
,
Mar 29 2017
> The given example file gives a DOM exception. I'm not sure how to fix that, > maybe turn off security checks locally. OK, I used a local web server, so the files could get loaded via http: not file:. Disabling some security checks should work as well. The st package for node can be used for this, see https://www.npmjs.com/package/st for details. > But in any case, the worker is using canvas. The worker is no accessing the canvas directly. It is creating ImageBitmaps, which get drawn to the canvas on the main thread.
,
Mar 29 2017
,
Apr 3 2017
,
Apr 3 2017
As far as I can tell the JS code is doing everything right. I see that the code is taking advantage of the transferability of ImageBitmap in the calls to postMeassage. That's good. I also see that the onmessage handler on the other side is correctly disposing of old ImageBitmaps by calling .close(). Those two measures combined should be sufficient to keep memory usage under control for ImageBitmaps even without garbage collection kicking in. This could be an internal bug in the ImageBitmap implementation.
,
Apr 3 2017
I haven't looked at details here so bear that in mind..but are (Static)ImageBitmaps registering their external allocations with v8 (AdjustAmountOfExternalAllocatedMemory())? If so, then transferring the bitmap objects to the worker would not transfer the cost from the worker's v8 context to the transferred context (and make that receiving context more eager to perform v8 GCs.) See issue 700353 for the ArrayBuffer case of this; SerializedScriptValue could easily accommodate ImageBitmaps for such alloc-cost transfers also.
,
Apr 6 2017
I have attached a minimal repro case: keep creating an ImageBitmap on a worker thread and transfer to the main thread and let main thread call close() method on the ImageBitmap. The above test case will eat about 1.5GB of ram in 3-5 seconds. However, if we un-comment the self.gc() line, then there is no memory leak at all. This indicate that the memory is garbage-collectable, it is just the case that GC is not actively triggered. I have a WIP CL: https://codereview.chromium.org/2796103002/, which should solve the problem in theory, but it doesn't. Another finding I have is that when running the attached test case, the constructor of the UnacceleratedStaticBitmapImage gets heavily called, but the destructor never gets called, even though the ImageBitmap's destructor is actively being called, and I am not sure why is that.
,
Apr 6 2017
,
May 5 2017
,
May 5 2017
The memory leak has gone with ToT code. I think our GC has done a much better job now:). |
||||||||
►
Sign in to add a comment |
||||||||
Comment 1 by tkent@chromium.org
, Mar 27 2017