The weak reference might explain one of the problems I had when running 10e6 tests. (I find them unpredictable but that might be because I avoid them so it's circular.)

The heap was growing unexpectedly as it was keeping things around, and into the long term area, when I thought they were open to GC'ing. In the end, I manually cleared the ThreadLocal value as well as removing it, kept the heap size constant, the long term area small, and no major GCs.

        Andy

On 17/03/15 12:01, Stian Soiland-Reyes wrote:
On 17 March 2015 at 11:33, Andy Seaborne <[email protected]> wrote:
I've ended up in a new system [*] heavily depending on ThreadLocals to
manage transaction state.  I did discover you have to carefully remember to
.remove them; they are quite chunky and have non-GC state.

Has anyone got any other practical advice or using them?  Performance
implications?

I've used them a lot. They should go when the Thread dies.  So if you
use Thread pools it gets a bit trickier.. but the ThreadLocalMap uses
WeakReferences - so if your reference to the ThreadLocal goes out of
scope, then it should also (eventually) be GC-ed.


  * <p>Each thread holds an implicit reference to its copy of a thread-local
  * variable as long as the thread is alive and the <tt>ThreadLocal</tt>
  * instance is accessible; after a thread goes away, all of its copies of
  * thread-local instances are subject to garbage collection (unless other
  * references to these copies exist).




Here's how I used it to get thread-safe JAXB marshallers.. probably a
bit awkward.

https://github.com/apache/incubator-taverna-language/blob/master/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/T2FlowParser.java


Here's the JDK's implementation: (GPLv3):


https://github.com/stain/jdk8u/blob/master/src/share/classes/java/lang/ThreadLocal.java#L161

The ThreadLocalMap is kept as a field of the Thread:

https://github.com/stain/jdk8u/blob/master/src/share/classes/java/lang/ThreadLocal.java#L232

and it has weak references back again to the ThreadLocal within the
entry that keeps the value
https://github.com/stain/jdk8u/blob/master/src/share/classes/java/lang/ThreadLocal.java#L298

so the values should stay alive as long as both the ThreadLocal is
other-wise reachable, and the Thread is still alive (and you have not
called that ThreadLocal.remove() button)



I've not seen any performance issues - that it can do lazily
initialization of the value per thread is quite nice. If you see in
the ThreadLocalMap above you see the tables are quite light-weight,
optimized for Threads not usually having many ThreadLocals.




         Andy

[*] WIP: It's public on my github account.


You are not going to lure me in!



Reply via email to