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
ThreadLocal Hubs should be cleaned up #2079
Comments
|
#2076 only allows Threads that had any |
We could do it similar to this: sentry/src/main/java/io/sentry/servlet/SentryServletRequestListener.java |
Is there any way to avoid the memory leaks in tomcat 9 caused by this issue? It's is causing developers to have to restart tomcat whenever we have redeployed applications a few times. |
Hello @adamnegaard what frameworks are you using? Is it Spring? Spring Boot? WebMVC? WebFlux? Basically the idea here is to call |
Hi @adinauer, thanks for taking the time to get back to me. Whenever we undeploy an app, tomcat is not able to unload classes, which have been loaded by the app. It seems like the reason for this is the static reference to a ThreadLocal here, which cannot be terminated on application undeploy: What i have tried so far, is creating a
I can see that this method gets invoked on undeploy, but it does not seem to be fixing our memory leak. Is there any known workaround for this issue? Otherwise, could you give me any pointers to where Sentry requests are performed, so i can try unsetting the hub reference after a request is done? |
@adamnegaard the problem here is that we set the thread local on every thread where interaction with the Sentry SDK happens. So basically on undeploy you'd have to go to every thread and unset the current hub there as there's no way to unset from another thread. The appenders I'm not entirely sure how this works in Tomcat but my guess is there's only a few threads that survive a redeploy and those would have to be cleaned up. Not sure you can register some callback that is invoked on each of those threads to then unset the hub.
Unfortunately the current workaround is restarting Tomcat. You could try to do the following:
This is what we do for WebFlux. So far there's no complaints for that approach so we could change WebMVC to do the same, i.e. clone a new hub when the request starts and unset the hub when it finishes instead of calling If you decide to give this a try, please leave some feedback 🙏
It's not just requests to Sentry. It's any request that comes into your server that then likely creates a hub instances and binds it to the current threads thread local variable for every thread that is used during the request. |
@adinauer I did try this approach, but does not seem to solve the problem. A It seems like the best solution would be moving away from |
Hello @adamnegaard have you tried this locally? Does it fix the problem? I've tried something very similar before and ran into multiple issues (need to check where I wrote them down). This requires lots of testing. Not sure when I'll get to that - apologies. |
Sorry for getting back so late to this. I have not testet it locally. Do you have any tips on how the best way to that might be? Also wondering if there are any other updates to this issue, that might be worth looking into? |
Hey, I replied on #2711 (comment) |
Problem Statement
At the moment Hub instances are stored in
ThreadLocal
variables. They are never cleaned up and thus cause servers like Tomcat to issue warnings as can be seen here #2074, here #420 and here #487. While there are mechanisms to clean up these leaks in Tomcat we should not rely on them and clean up instead.sentry-java/sentry/src/main/java/io/sentry/Sentry.java
Line 21 in 9f1af1c
Solution Brainstorm
We may have to move away from
ThreadLocal
variables at some point to support Webflux and similar. Until then we could try and unset theThreadLocal
after a request is done (ServletRequestListener.requestDestroyed
)The text was updated successfully, but these errors were encountered: