Search code examples
javascriptarraysmemory-leaksgarbage-collectionflush

How to avoid possible memory leak at flushing an array stored in Promise.all()


I'm playing with mail sending logic and the following code works as expected: for every recipient it builds an email content and sends it to a person:

recipients.forEach((recipient) => {

    orders.forEach((order) => {
        if (order.ownerID === recipient.userID) {
            emailContent.blocks.push({
                content: "%EMAIL_TEXT%"
            });
        }
    });

    promises.push(mailer.sendEmail(recipient, emailContent));
    emailContent.blocks = [];
});

await Promise.all(promises);

The only questionable moment is they way I flush the array before I start building a new email:

emailContent.blocks = [];

I send the original content of emailContent.blocks to mailer.sendEmail() by storing it in promises array and then assign a new array to emailContent.blocks. Which might theoretically lead to the memory leak.

Do I need extra care about abandoned emailContent.blocks in this case? Or after finishing await Promise.all(promises); and exiting from a function garbage collector will do the job?

I just want to be sure that this code doesn't generate a memory leak.


Solution

  • Looks very much like something the garbage collector will clean up. I would be more worried about changing emailContent.blocks after you just sent emailContent to mailer.sendMail.

    Since emailContent is sent by reference, settings emailContent.blocks = [] will alter the value in mailer.sendMail.

    It might work now but if sendMail ever becomes asynchronous (or just slower) then you'll have some really hard to solve bugs on your hand.

    Not exactly sure what lies behind the emailContent variable but I'd suggest making a new emailContent variable every loop if possible.

    And as Andreas suggested, use a profiler when in doubt.