-
Notifications
You must be signed in to change notification settings - Fork 426
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
ActivityCorrelator is causing a classloader leak #314
Comments
Thanks for the quick fix, @v-nisidh! The leak in my particular case is fixed, because I don't use a connection pool for the task I'm using mssql-jdbc for. I use Spring Framework's JdbcTemplate to open a new connection, execute a single SQL query and close the connection. All this happens in the same thread, so the current fix works just fine. However, as @marschall mentioned in #321, this fix won't work for a more traditional case with a web application running on an application server that uses a connection pool, because different threads can be used to open and close the same connection, and ThreadLocal.remove() doesn't have an effect as it can only clean up ThreadLocal for the thread it's called from. Here's the source code for ThreadLocal.remove()
As you can see it uses the ThreadLocalMap from the current thread, so there's no easy way to clean up another thread's ThreadLocal. I would suggest considering using InheritableThreadLocal instead of ThreadLocal to avoid this limitation or even better not use ThreadLocals at all, if possible. @marschall You are correct that it's recommended to deploy JDBC drivers to the application server itself, but it's only because of the way DriverManager works, see https://stackoverflow.com/questions/6981564/why-must-the-jdbc-driver-be-put-in-tomcat-home-lib-folder. But it's no longer a problem if you unregister the driver from DriverManager during ServletContext shutdown. There are some cases when it's useful because it's undesirable or impossible to modify the application server's configuration. However leaky JDBC drivers create a problem in this scenario. The leak still exists when the driver is deployed on the application server level, it's just hidden because the driver classes are loaded by the app server's own classloader, which is never supposed to be garbage collected anyway. Other JDBC drivers I used - Oracle and MySQL don't have a leak. |
Thanks for the contribution. as @JohnA2 suggested, I believe it would be the best approach to remove using ThreadLocal in this case, for a couple of reasons:
I opened a new PR for this issue: #465 |
ActivityCorrelator uses ThreadLocal, but it never calls ThreadLocal.remove() to clean it up. As a result, if a thread pool is used, the classloader that loaded ActivityCorrelator can never be garbage collected thus creating a memory leak.
Example of the path from GC root:
The text was updated successfully, but these errors were encountered: