Reputation: 3
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
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