Description
Pasted from https://stackoverflow.com/questions/74852458/memory-leak-with-redux-toolkits-createlistenermiddleware
Original Report
I use Redux Toolkit, and in particular the new listener api, to perform tasks similar to what I could do with Redux-Saga.
Unfortunately, since a few days, I'm stuck with a memory leak and I can't find the cause.
I have reproduced a minimal example of the code that produces this memory leak, link to the example : https://github.com/MrSquaare/rtk-memory-leak
To observe this memory leak :
- I use Chromium, DevTools memory tool
- I trigger a garbage collector
- I make a heap memory snapshot
- I dispatch entity/load (via the UI button)
- I make several heap memory snapshots every 2-3 seconds
- I use the comparison tool, I notice that I have the array allocation size growing infinitely
And after dispatch entity/unload, then make a snapshot heap memory, we can observe that the allocations disappear...
Has anyone observed similar behavior? Or does anyone have an idea of the cause? Thanks!
EDIT 1:
I made an example with only the listener middleware (only-middleware
branch), and compared it with different ways of doing :
- With
forkApi.pause
: Important leaks, especially of the generated entities - Without
forkApi.pause
: I use directlyapi.dispatch
, no more leaks of the generated entities, some leaks of other kinds, but maybe normal things (I am not qualified enough to pronounce on this) - Without
api.dispatch
: I call directly the function that generates an entity, same result as withapi.dispatch
It seems that the leak is related to forkApi.pause
, but again I am not qualified enough to know the real cause...
Other Notes
Lenz pointed to nodejs/node#17469 (comment) - it may be related to use of Promise.race()
:
export const createPause = <T>(signal: AbortSignal) => {
return (promise: Promise<T>): Promise<T> => {
return catchRejection(
Promise.race([promisifyAbortSignal(signal), promise]).then((output) => {
validateActive(signal)
return output
})
)
}
}
Lenz's note:
So the problem is that promisifyAbortSignal will stick around for a very long time