denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
96.82k stars 5.35k forks source link

Web Workers use 7x more memory than in Chrome, and terminating them doesn't remove all the memory #26058

Open josephrocca opened 2 weeks ago

josephrocca commented 2 weeks ago

Version: Tested in Deno 1.46.x and 2.x

The code below creates 100 workers, then waits 5 seconds, then terminates them, and repeats.

while(1) {

let workers = []; for(let i = 0; i < 100; i++) { const workerBlob = new Blob([ delete globalThis.Deno; self.onmessage = async function(e) { self.postMessage('Hello from Worker!'); } ], {type:"application/javascript"});

const workerURL = URL.createObjectURL(workerBlob);
const worker = new Worker(workerURL, {type:"module"});

worker.onmessage = function(e) {
  URL.revokeObjectURL(workerURL);
  console.log('Received from worker:', e.data);
};
worker.postMessage('Hello from main thread!');

workers.push(worker);

}

await new Promise(r => setTimeout(r, 5*1000));

for(let w of workers) w.terminate(); workers = [];

}

Hajime-san commented 2 weeks ago

Maybe this could be related about memory usage.

I think the slowdown is a combo of the byte array copy in op_postmessage and Deno.core.serialize and Deno.core.deserialize being seperate calls.

nathanwhit commented 2 weeks ago

I believe the cause of the increased memory usage is due to us not being able to enable shared RO heap in V8 (the reason is rather complicated, but once V8 fixes the issue we'll be able to enable it). So where chrome has one copy of globals shared across all isolates, we have a copy per isolate. The globals take up about 7-8MB, which would account for much of the extra memory.

Not sure about the memory not being freed, though

josephrocca commented 1 week ago

@nathanwhit Thanks for your comment! I've investigated this a bit further, and it looks like the "leaked" memory actually maxes out at about 500mb, no matter how many workers are created+destroyed, so this may actually be expected behavior - i.e. due to some sort of reuse resource pool, or something. This is a non-issue for me, so unless you suspect this is buggy behavior, this is probably not worth investigating further for now.

RE the "shared RO heap", I'm looking forward to that. Do you know of any v8 crbug or Deno issue/pull request that I can subscribe to for updates?

nemosmithasf commented 4 days ago

Wanted to add volume to this: I also experience memory leaking from large amounts of workers being created/destroyed