Skip to content
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

[Memory leak] Context is not cleared if it references a Promise #66

Open
MayurRJoshi opened this issue May 31, 2021 · 0 comments
Open

Comments

@MayurRJoshi
Copy link

Summary
If the context contains a key which references a Promise, then that context object is never cleared. Hence, the _contexts map keeps growing and hogs up all the heap memory.

Steps to reproduce

  1. Install express and cls-hooked.
  2. Run the script below, node --inspect index.js
const express = require('express')
const clsHooked = require('cls-hooked')
clsHooked.createNamespace('test')

const app = express()

app.get('/', (req, res, next) => {
    const namespace = clsHooked.getNamespace('test')
    
    console.log(namespace._contexts)

    namespace.run(() => {
        namespace.set('x', Promise.resolve())
        res.json({})
    })
})

app.listen(3030, () => console.log(('Listening')))
  1. Call the server api, curl localhost:3030
  2. [Optional] Manually trigger a garbage collection from the Chrome debugger.
  3. Repeat 3 and 4 and observe the logs. Notice that the _contexts keeps growing even after a manual garbage collection
node --inspect index.js 
Debugger listening on ws://127.0.0.1:9229/05303a92-c1ac-4cdb-816a-4b5e15de611a
For help, see: https://nodejs.org/en/docs/inspector
Listening
Debugger attached.
Map {}
Map {
  16 => { _ns_name: 'test', id: 11, x: Promise { undefined } },
  22 => { _ns_name: 'test', id: 11, x: Promise { undefined } } }
Map {
  16 => { _ns_name: 'test', id: 11, x: Promise { undefined } },
  39 => { _ns_name: 'test', id: 34, x: Promise { undefined } } }
Map {
  16 => { _ns_name: 'test', id: 11, x: Promise { undefined } },
  39 => { _ns_name: 'test', id: 34, x: Promise { undefined } },
  61 => { _ns_name: 'test', id: 56, x: Promise { undefined } } }
Map {
  16 => { _ns_name: 'test', id: 11, x: Promise { undefined } },
  39 => { _ns_name: 'test', id: 34, x: Promise { undefined } },
  61 => { _ns_name: 'test', id: 56, x: Promise { undefined } },
  84 => { _ns_name: 'test', id: 79, x: Promise { undefined } },
  90 => { _ns_name: 'test', id: 79, x: Promise { undefined } } }

If I change the set to namespace.set('x', '') (or any other primitive or object), context is cleared sometimes automatically after every request and always if a manual garbage collection is triggered.

Output with no manual GC.

node --inspect index.js 
Debugger listening on ws://127.0.0.1:9229/d39a47e8-72a2-4603-885a-ba0e3dbd8d53
For help, see: https://nodejs.org/en/docs/inspector
Listening
Map {}
Map { 21 => { _ns_name: 'test', id: 11, x: '' } }
Map {}
Map {}
Map {}
@MayurRJoshi MayurRJoshi changed the title [Memory leak] Context is not cleared if namespace references a Promise [Memory leak] Context is not cleared if it references a Promise Jun 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant