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

AbortSignal.any memory leak when circular dependencies #57584

Open
CGNonofr opened this issue Mar 21, 2025 · 0 comments
Open

AbortSignal.any memory leak when circular dependencies #57584

CGNonofr opened this issue Mar 21, 2025 · 0 comments

Comments

@CGNonofr
Copy link

Version

23.10.0

Platform

6.8.0-55-generic #57-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 12 23:42:21 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

class Test {
  private abortController = new AbortController()

  public test(cb: (abortSignal: AbortSignal) => void, abortSignal: AbortSignal) {
    const signal = AbortSignal.any([abortSignal, this.abortController.signal])

    cb(signal)
  }
}

const registry = new FinalizationRegistry((heldValue) => {
  console.log(`${heldValue} has been collected`)
})

;(() => {
  const test = new Test()
  registry.register(test, 'test')

  const abortController = new AbortController()

  test.test((abortSignal) => {
    abortSignal.addEventListener('abort', () => {
      console.log(test)
    })
  }, abortController.signal)
})()

global.gc?.()

setTimeout(() => {
  console.log('the end')
}, 2000)

run with node --expose-gc test.ts

How often does it reproduce? Is there a required condition?

Every time

What is the expected behavior? Why is that the expected behavior?

the output should be

test has been collected
the end

because the test object is not referenced anymore

What do you see instead?

output:

the end

the test object is not garbage collected

Additional information

The issues seems to be caused by the cyclic dependency: test object => abortController field => abortSignal => AbortSignal.any result => cb function => test object

AbortSignal.any seems to prevent node from garbage collecting them all at once

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