Home > database >  Does it cause a memory leak for a WebWorker to postMessage to CPU intensive tasks?
Does it cause a memory leak for a WebWorker to postMessage to CPU intensive tasks?

Time:04-25

Let's say I had a WebWorker file called ticker.js that consisted of this:

function tick() {
  postMessage(1);
}

setInterval(tick, 1);

And then in the main JavaScript program I had this:

let ready = true;
let prevTime = 0;

function sometimesLongTask() {
  ready = false;

  if (performance.now() - prevTime > 30) {
    // a very long CPU intensive task, like a loop which takes a while to complete

    prevTime = performance.now();
  }

  ready = true;
}

const intervalWorker = new Worker('ticker.js');

intervalWorker.onmessage = function() {
  ready && sometimesLongTask();
};

Would this cause a memory leak?

I think it won't, but I'm not sure. My logic is that while sometimesLongTask will sometimes take a while (when 30 milliseconds have passed), 99% of the time it will execute immediately. As such, even though a new tick is added to Javascript's event queue every millisecond, every once in a while Javascript can speed through all of those and clear them out since the majority of them will not need to execute. Is this indeed the case?

Also, do I even need the ready flag here, or is it doing nothing (and I can get rid of it)? I think it might be doing nothing because Javascript is single-threaded, so even though the WebWorker might post multiple messages very quickly, Javascript cannot run multiple instances of sometimesLongTask at the same time. Correct?

CodePudding user response:

Yes, this won't cause a memory leak, since that by definitions means memory allocations not being released despite no longer being needed. The events in the message queue are still needed though, they will eventually be received by the worker.

But you won't even get growing memory usage. This is solely due to the prevTime comparison though - we can assume that all queued events can be handled (by doing nothing) in the 30ms between the runs of the long task.

Do I even need the ready flag here, or is it doing nothing?

It indeed does nothing useful. Notice it is always true when the onmessage handler is executed. The onmessage handler will never interrupt your synchronous sometimesLongTask during which it is set to false.

  • Related