• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

ThreadLocal and GC

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Any ideas/comments?
 
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
An idea: TellTheDetails.
 
Sergey Alaev
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Details are simple: as above test shows, ThreadLocal values are NOT garbage collected if not removed manually from ThreadLocal instance, even if we have no strong references to our ThreadLocal instance.
This seems illogical to me....
 
Bartender
Posts: 3225
34
IntelliJ IDE Oracle Spring Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
From the Documentation for the ThreadLocal


Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal 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).



And you really cannot force the Garbage collection by using System.GC().
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are you sure that the thread that executed before() has terminated (and was eligible to be garbage collected, so the JUnit framework didn't keep any reference to it) sooner than the test() and test2() were called? I don't know the JUnit internal mechanisms well enough to tell.

Besides, I'd say that PhanthomReference and reference queues are more robust mechanism for determining when an object was garbage collected. Then you could monitor collection of the owning thread too, or better write the test outside any framework, so that you have full control over references to threads that were used.

What Mohamed said should also be considered.

Edit: thread locals should really get cleared when the thread terminates, not when it is garbage collected. I had thought otherwise.
 
Sergey Alaev
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mohamed Sanaulla wrote:From the Documentation for the ThreadLocal


and the ThreadLocal instance is accessible;




This is not the case - i've deleted reference to ThreadLocal instance as you can see.
About System.gc() - you are right, but usually(and in this case) it works as intended. You can use any good profiler to see that GarbageObject will not be garbage-collected anyway.


 
Sergey Alaev
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
2Martin Vajsar

Both tests are running in the same thread, but that is not the case.
Problem is that any value hold in ThreadLocal instance is indirectly referenced by Thread instance - i.e. in my case GarbageObject will NOT be collected before current thread finishes.

Actually, i hoped that GarbageObject will be collected after i destroyed reference to ThreadLocal instance - why not?
 
Sergey Alaev
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Martin Vajsar wrote:
Edit: thread locals should really get cleared when the thread terminates, not when it is garbage collected. I had thought otherwise.



Thus, the question is why it has been designed this way?
thead locals are inaccessible anyway without appropriate instance of ThreadLocal
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sergey Alaev wrote:
This is not the case - i've deleted reference to ThreadLocal instance as you can see.



The Threadlocal class actually stores the values in the Thread object itself -- so interestingly, you actually don't need to make the ThreadLocal instance unreachable. It is perfectly fine to keep the references to it.

On the other hand, the Thread object needs to be unreachable -- meaning the thread that set the thread local value needs to terminate, and no other thread is holding a reference to that thread's Thread object.


[EDIT: A bit more detail. On the third hand, I was also under the impression that the value is stored in a weak map, that is keyed on the thread local. This would imply that if the thread local goes, then the running thread loses it too.... meaning the value is eligible for GC if either the Thread object or ThreadLocal object becomes unreachable.]

Henry
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:
On the other hand, the Thread object needs to be unreachable


It should not be so. Firstly, the documentation states that values are kept while the thread is alive, not while it is referenced, and secondly, the exit() method in Thread that is called by the JVM when thread terminates clears the local values of the thread, as can be seen in the JDK source.
 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I may be wrong, but isn't a thread always reachable as long as it's alive?
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:I may be wrong, but isn't a thread always reachable as long as it's alive?


It certainly is, but on the other hand, it may be reachable long after it had terminated. The thread locals are cleared when it terminates, not when it becomes unreachable.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Martin Vajsar wrote:

Stephan van Hulst wrote:I may be wrong, but isn't a thread always reachable as long as it's alive?


It certainly is, but on the other hand, it may be reachable long after it had terminated. The thread locals are cleared when it terminates, not when it becomes unreachable.



Wow, this is a fast moving topic. I just changed my last post -- only to find out that it is three posts behind, and my last edit may never be read.

I now think that the value should become unreachable, when the thread local becomes unreachable too -- maybe it would be a good idea to modify the test harness to call system.gc() a few times (or in a loop). And see if it eventually disappears.

Henry
 
Sergey Alaev
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:
I now think that the value should become unreachable, when the thread local becomes unreachable too -- maybe it would be a good idea to modify the test harness to call system.gc() a few times (or in a loop). And see if it eventually disappears.

Henry



It will not disappear because as i've written above it is hard-referenced to current Thread instance.
Question now is WHY it is hard-referenced
Because i cant believe it is a bug.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Duh... I forget that weak hash maps needs to be used in order to clear entries. Only the key is weak. And there isn't a thread that will clear them periodically. After the GC, try changing your test to create another thread local object, and using it; maybe that will trigger the Thread's weak hashmap to clear it's entries. And of course, GC again.

Henry
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Martin Vajsar wrote:
It should not be so. Firstly, the documentation states that values are kept while the thread is alive, not while it is referenced, and secondly, the exit() method in Thread that is called by the JVM when thread terminates clears the local values of the thread, as can be seen in the JDK source.



Yup. I stand corrected.

I just confirmed that the data is deleted upon thread termination -- it doesn't require the unreachability of the Thread instance.

Henry
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sergey Alaev wrote:
It will not disappear because as i've written above it is hard-referenced to current Thread instance.
Question now is WHY it is hard-referenced
Because i cant believe it is a bug.



Henry Wong wrote:I forget that weak hash maps needs to be used in order to clear entries. Only the key is weak. And there isn't a thread that will clear them periodically. After the GC, try changing your test to create another thread local object, and using it; maybe that will trigger the Thread's weak hashmap to clear it's entries. And of course, GC again.



This one is also confirmed, but it is a bit more complex. The trigger that will delete entries (if the thread is still alive but the thread local becomes unreachable), is a rehash of the weak map internal to the thread object. This requires creating a few thread local objects until the rehash occurs.

Henry
 
reply
    Bookmark Topic Watch Topic
  • New Topic