ircam-ismm / node-web-audio-api

Web Audio API implementation for Node.js
https://www.npmjs.com/package/node-web-audio-api
BSD 3-Clause "New" or "Revised" License
93 stars 12 forks source link

OfflineAudioContext: reuse or clean memory resources #133

Closed bthj closed 5 days ago

bthj commented 3 weeks ago

Hi!

When performing consecutive renders with the OfflineAudioContext, memory usage only accumulates, for example with repeated calls like below (ran with the --expose-gc flag).

It might seem like an approach to reuse the OfflineAudioContext instance (e.g. by instantiating it outside the loop), but that results in an error after the first iteration. Uncommenting the suspend / resume calls also results in an error after a few iterations.

Do you see any options to clean up the used resources in this example? - or would some modifications to the library be required?

import { OfflineAudioContext } from 'node-web-audio-api';

for( let i=0; i < 100000; i++ ) {
  console.log('+ i:', i);

  let offline = new OfflineAudioContext(1, 10*48000, 48000);

  // offline.suspend(128 / 48000).then(async () => {
    const osc = offline.createOscillator();
    osc.connect(offline.destination);
    osc.frequency.value = 220;
    osc.start(0.);
    osc.stop(10.);

  //   await offline.resume();
  // });

  const buffer = await offline.startRendering();
  console.log('+ buffer duration:', buffer.duration);

  offline = null;

  if (global.gc) {
    global.gc();
  }
}

Running this on Apple M1 Pro

b-ma commented 2 weeks ago

Hey, thanks for the report

From what I see after small testing the OfflineContext is never garbage collected, so this is a memory leak issue within the lib... The only workaround I can think of for now is to spawn / fork a new process on each iteration, very not ideal and a lot more inefficient but this should work until the issue is fixed

Still on holidays until beginning of September on my side, but I try to have a closer look as soon as possible

bthj commented 2 weeks ago

Thanks @b-ma !

I’ll try forking for now :)