1
{
  const data = new Uint8Array([0x01]);
  await input_writer.write(data);
}

In the above example, 'data' is passed to an async operation, and then immediately scopes out. What happens to the underlying memory? Does it stay alive until the async function is finished with it?

user1043761
  • 696
  • 6
  • 22
  • GC will only collect unreachable/unused data. – ASDFGerte Jan 07 '22 at 18:02
  • Maybe helpful - https://stackoverflow.com/a/54322111/743464 - maybe implementation specific. It probably stays alive until nothing references it and and a javascript blocking garbage collection pass runs. – Andy Ray Jan 07 '22 at 18:02

1 Answers1

0

At first I thought that data was only garbage collectable at the end of the code block, but it seems that the JavaScript engine is smarter than I thought.

Indeed, when executing this snippet:

class Test {}

(async function() {
  const data = new Test;
  await write(data);
  console.log('never');

  function write(data) {
    return new Promise(() => {});
  }
})();

Then using the "Memory" tab to take a memory snapshot, no Test shows up when searching it.

However, if you try this snippet and take a new snapshot, then the instance shows because this implementation of write passes data to setTimeout which keeps a reference on data for a certain time:

class Test {}

(async function() {
  const data = new Test;
  await write(data);
  console.log('in a long time');

  function write(data) {
    return new Promise(resolve => setTimeout(() => resolve(data), 999999999));
  }
})();

Note: you have to paste it in your console to see it in the memory snapshot.

As a conclusion, if write has no side-effect which saves a reference on data, the JavaScript engine (chromium at least) seems to be smart enough to determine that data won't be used anymore even before the end of the code block, which helps clear the memory as soon as possible.

Guerric P
  • 30,447
  • 6
  • 48
  • 86