William TC
William TC

Reputation: 3

How to avoid memory leaks with the use of Node Streams and promises

I try to wrap node streams in an async function. But I'm wondering if the following code leaks memory. Will readStream and result be garbage collected after the promise is resolved(rejected)? If not, how should I avoid the memory leak?

async function readFile(path, keyword) {
  const readStream = fs.createReadStream(path, {encoding: 'utf8'});
  let result = await getCachedResult(); // getCachedResult is another async function
  return new Promise((resolve, reject) => {
    readStream.on('data', (chunk) => {
      if (chunk.includes(keyword)) {
         result += chunk;
      }
    })
    readStream.on('error', (err) => {
        reject(err)
        readStream.close()
    })
    readStream.on('end', () => {
        resolve(result)
        readStream.close()
    })
  })
}

Upvotes: 0

Views: 1218

Answers (1)

traktor
traktor

Reputation: 19301

Currernt JavaScript memory garbage collection algorithms are based on removing data objects and values (including environment record objects containing function variables and parameters) that can't be reached in code.

So what data objects and values inside the async function readFile body are reachable after it returns a Promise object?

No references to path or keyword are retained after returning, so they are eligible for GC.

References to readStream, result, resolve, reject chunk, and err are only held by the anonymous functions handling stream events registered on the stream.

The handler functions are reachable from the readStream instance object ( or its event emitters).

The readStream object is responsible for removing references to callbacks that can no longer be made: either after the end event itself, or after calling readStrem.close. Either way you don't need to be concerned about creating memory leaks by using promises or read streams.

Upvotes: 2

Related Questions