question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory leaking with Promise.map concurrency

See original GitHub issue
  1. What version of bluebird is the issue happening on? Bluebird 3.5.20 with bluebird-global 3.5.5

  2. What platform and version? (For example Node.js 0.12 or Google Chrome 32) Node.js 8.9.

  3. Did this issue happen with earlier version of bluebird? As far as I know

I have code that looks like this:

const aBunchOfIds = [ /* a few hundred thousand elements */ ]
Promise.map(aBunchOfIds, async id => {
    const anObj = await getFromDatastore(id);
    const anotherObj = await process(anObj);
    if (isSpecial(anotherObj)) { console.log('so special'); }
}, { concurrency: 1000 });

This dies because node runs out of heap space. However the following modification resolves the issue:

const aBunchOfIds = [ /* a few hundred thousand elements */ ]
for (let i = 0; i < aBunchOfIds.length; i += 10000) {
    const someIds = aBunchOfIds.slice(i, i + 10000);
    Promise.map(someIds, async id => {
        const anObj = await getFromDatastore(id);
        const anotherObj = await process(anObj);
        if (isSpecial(anotherObj)) { console.log('so special'); }
    }, { concurrency: 1000 });
}

So it seems that Promise.map doesn’t free the memory used by its promises until all promises have returned, even when a concurrency is specified.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:6
  • Comments:15 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
0xgeertcommented, Feb 2, 2019

I’m seeing memory-leak issues that are very similar, if not the same.

Came up with the following test-case which shows the issue clearly:

  • running below code as-is will result in OOM in a couple of seconds
  • running code with then() added (see below) will allow GC to free up mem.

Lodash 3.5.2


/*
 Below gives an OOM in a couple of seconds. 
 Adding the commented-out then() solves it. Why?
 */
const Promise = require("bluebird");
const obj = {a: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
return Promise.map(new Array(100000), () => {
  return Promise.resolve()
  .then(() => new Array(10000).map(() => Object.assign({},obj))) //consume some mem
  // .then(() => { //passing in an argument here, makes the OOM-issue reappear
  //   //adding this then(), will allow objects to be GC'ed, thus solving OOM-issue. WHY?
  // });
}, { concurrency: 10 })

It seems that since the result isn’t passed in as argument to the last then() the object can be freed from mem. This seems to suggest that not only the promises themselves but all objects created inside those promises are kept locked in mem until the entire Promise.map is finished.

1reaction
krunkosauruscommented, Jan 3, 2019

Just a heads up that I got “Maximum call stack size exceeded” errors until I finally downgraded this package to 3.5.2

I think it could be related to this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to resolve memory leak in node.js due to .map function
I am running into a memory issue which I suspect is due to my map functions.( Bluebird Promise.map). The below Myfucntion() calls the ......
Read more >
Looping over await Promise.all memory leak : r/javascript
I run over 500 000 uids to fetch their associated data via a promise (promiseUserData(uid)). For some reason the memory usage is not...
Read more >
The 4 Types of Memory Leaks in Node.js and How to Avoid ...
A look at memory leaks in caching and promises. a concrete building wall with an open window and ... Caching is the most...
Read more >
Introduction - Alexandru Nedelcu
As you'll see, there are some reasonable arguments for why the Promise implementation is allowed to leak memory. But I can't agree.
Read more >
Promise.map - Bluebird JS
Map Option: concurrency ... You may optionally specify a concurrency limit: ...map(..., {concurrency: 3});. The concurrency limit applies to Promises returned by ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found