-
Notifications
You must be signed in to change notification settings - Fork 17
Description
We've been trying to track down a memory leak which has been killing our prod boxes. Eventually, with the help of the heapdump module, we've been led to believe that it has something to do with either trycatch, or the way we use it. See attached screenshot of profile.
The doCatch function is the closure we pass as the catchFn to trycatch, and onError and onMessageHandled are functions referenced from doCatch.
According to the profile, it seems that these functions can't get cleaned up due to persistent references from inside trycatch, in particular via the _trycatchOnError function. This function in turn creates a reference from the child domain to the parent domain. It does this via
Line 58 in 0fc57b3
| d.on('error', _trycatchOnError) |
Line 98 in 0fc57b3
| handleException(err, parentDomain, catchFn) |
To test this theory, I hacked trycatch locally to pass a callback to the tryFn (incidentally the catchFn doesn't need to get invoked to create to the leak). This callback would then remove the listener added at
Line 58 in 0fc57b3
| d.on('error', _trycatchOnError) |
I'm not sure whether this is a feasible route to go down though, as handling the error case, where the catchFn actually needs to be called, which itself could fail, would be challenging.
What is also confusing is that we do use trycatch elsewhere and I haven't seemed to notice any leaks there, though that could be due to us using it at much larger scale in this use case, which makes the leaks visible.
