tommie tommie - 1 year ago 93
Javascript Question

Memory leak with Web Worker / Canvas


Using Chrome, launch Task Manager (Shift+ESC), click the worker invert button a few times, each time it goes up ~10 MB. Anytime I receive a message back from the worker the memory goes up, it's not from modifying or accessing the canvas, it happens when the worker sends the message back to the main thread. It gets worse the larger the message is.

Adding the ImageData buffer to the optional transferables list on postMessage doesn't make a difference, same result, I'm wondering if there's another way I should approach this.

imageData = ctx.getImageData(0, 0, 800, 600);
worker.postMessage(imageData, []);

Still doesn't matter if the main thread and/or worker thread is transferring ownership. I can see in the console that the imageData object actually transfers ownership, but the memory still increases! I've tried memory profiling with chrome dev tools but I can't see where the increase is at.

Forcing GC in dev tools clears the memory. Sometimes GC runs automatically, sometimes it doesn't, when it does, it only releases like 10% of what's been allocated.

I've read a lot of pages last night but they all say the same thing and I feel like I am overlooking something simple.

Transferable objects:


Chrome Version 48.0.2564.116 beta-m (64-bit)


Added a loop option, seems like the only way to release the memory is to terminate the thread, I wanted to avoid creating new threads each time though and just keep one open because there is a noticeable delay when creating a new one each time

Answer Source

You dont have a memory leak. This is just normal GC behaviour and there is not much you can do to stop the seemingly excessive memory use.

I had a play with your fiddle changing the code so that the worker.onmessage function immediately called startWork, effectively putting it in a loop, send the data, receive the inverted data set, put it on the canvas, then call startWork again and let it go while I had a coffee. It ran just fine.

Watching processes on chrome 49.0.2623.47 beta-m the memory useage peeked at about 110mb but never runs out of memory. Both Heap allocations and Timeline show normal behaviour and no leaks. Chrome has made some changes to GC so that it defers its actions in favour of the DOM and Javascript which may, if you are not used to it, look like memory usage has gone up, It is nothing to worry about. All that matters is that when you need memory it is available. GC will clean up if critical low memory, and it is better to have some dead memory rather than block the DOM or Javascript when they are busy, just to dump some unneeded memory.