Fiddle: https://jsfiddle.net/eimmot/065wxa9o/9/
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, [imageData.data.buffer]);
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: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects)
Chrome Version 48.0.2564.116 beta-m (64-bit)
Fiddle: https://jsfiddle.net/eimmot/065wxa9o/13/
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
I've found a solution that works for me in Chrome. I made two major modifications to the looping version of your fiddle:
imageData.data.buffer
to the transfer list when returning it from the workerimageData.data
, instead of the entire imageData objectHere's the modified fiddle: https://jsfiddle.net/065wxa9o/14/
Note that just adding the buffer to the worker's transfer list doesn't work (https://jsfiddle.net/065wxa9o/15/) I have to transfer just the typed array.
Chrome Version 52.0.2743.116 (64-bit)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With