-
Notifications
You must be signed in to change notification settings - Fork 2.3k
OutOfMemory due to results in chain retained #1529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
My quick guess would be that it doesn't have to do with the chain ending, but rather with your callbacks not doing anything asynchronous - bluebird might schedule all of them on the same tick, and keep the promises until the current round of synchronous work is over. Can you test by introducing a |
Bluebird keeps a circular buffer around as a queue that grows the more callbacks you have - its size is constant and it stays in the background for fast scheduling. It never shrinks but the memory isn't "leaked" - that is - the next time you'll schedule a promise it will be reused. |
You can see it here: https://github.com/petkaantonov/bluebird/blob/master/src/queue.js |
Introducing a The queue probably helps (or helped in earlier runtime versions) performance, but if this is what keeps a reference it has the effect that one must be careful of what is in closure of the callbacks if using large part of the available heap for one chain. This is not uncommon in for instance serverless microservices processing data. I am a complete noob to bluebird internals, but also wonder why there is a reference kept as shift() appears to dereference the entry in the queue (as used from async). Perhaps there is another problem (related to the scheduling?) I am not sure what an appropriate course of action is, but this is quite a gotcha so perhaps at least worth adding somewhere in the doxs? (and at least this issue might help others for now) |
What version of bluebird is the issue happening on?
3.5.1
What platform and version? (For example Node.js 0.12 or Google Chrome 32)
Node v8.11.1 on osx Darwin Kernel Version 17.5.0 x86_64
Did this issue happen with earlier version of bluebird?
Not sure
Using promise chains can cause unexpected OutOfMemory situations as the partial results in the chain seam to be retained until the entire chain is settled.
For example in this
promise-chain-retain.js
:Using node 8 vanilla promises this works as expected in a chain and in "use summary" step the big result is no longer retained and can be GC:ed:
When using Bluebird as Promise things do not work as expected. The result of the first then is still retained in "use summary" step.
Thus long chains in a request do not GC as expected if resolving large values. This example is simplified but imagine building a large object, converting to JSON, compressing and then sending to an external service - if at any step resolving the large object will not allow it to be GC:ed until the entire chain is done. Essentially at least doubling the memory requirement (or OOM given contained resources and large objects).
The text was updated successfully, but these errors were encountered: