For me I have to take care with thread locals both in our own code and
in a variety of 3rd party code, because of the possibility of
classloader mem leaks in a J2EE/OSGi environment.
See e.g.
https://issues.apache.org/jira/browse/SHINDIG-1132
for general background to this sort of problem
As a result, I track down and treat specially ThreadLocals which do not
call remove() in an appropriate fashion.
i.e. a well behave thread local, will call remove(), hopefully in a
finally block, as the thread exits back up the stack.
Sometimes this is difficult or impossible, and obviously some 3rd party
code I cannot influence very much, so I have workarounds.
In com.hp.hpl.jena.tdb.transaction.DatasetGraphTransaction there are two
thread locals, neither of which call remove() appropriately. In
particular, remove() cannot be called on the finalizer thread.
Note, remove() does not create the ThreadLocal if it currently has no value.
My suggestion would be to call remove on both ThreadLocals in this class
on all of the methods that exit a transaction (end(), abort(), commit()).
I would be happy to provide a patch to this effect, (I realize I already
owe a couple of patches)
For more background, see e.g.
http://cs.oswego.edu/pipermail/concurrency-interest/2007-October/004476.html
for some more discussion. This general situation is made a lot worse by
the previously mentioned JVM bug, which can create issues with weak
references as well as strong - given that this is a GC bug that I do not
understand it is very hard to know which weak references matter and
which don't.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7146977
Jeremy