Promptly freeing the per-thread cached direct buffers when a thread exits

Peter Levart peter.levart at
Fri Apr 6 12:49:13 UTC 2018

On 04/06/2018 10:02 AM, Alan Bateman wrote:
> On 05/04/2018 22:45, Tony Printezis wrote:
>> Hi all,
>> We recently hit another interesting issue with the NIO thread-local
>> DirectByteBuffer cache. One of our services seems to create and drop
>> threads at regular intervals. I assume this is due to a thread pool
>> dynamically resizing itself.
>> Let's say a thread starts, lives long enough for its Thread object to be
>> promoted to the old gen (along with its cached direct buffer), then 
>> exits.
>> This will result in its cached direct buffer(s) being unreachable in the
>> old gen and will only be reclaimed after the next full GC / 
>> concurrent GC
>> cycle.
> Right, if a short lived thread does I/O with a buffer backed by an 
> array in the heap then any direct buffers in its thread local cache 
> won't be freed until there is a GC and reference processing. It's 
> something that I've prototyped a few times and always leaned towards 
> not exposing anything in the API, instead just hooking into the thread 
> exit to clear the buffer cache. One thing to watch out for is that the 
> buffer cache may not exist (as the thread didn't do any I/O with heap 
> buffers) so you'll end up creating (an empty) buffer cache at thread 
> exit. That is benign of course but still unsettling to have additional 
> code executing at this time.
> -Alan

An internal method, let's say ThreadLocal.probe(), that would return 
thread-local value only if it has already been initialized, would be 
helpfull. Maybe it could be exposed as new public API too. I remember 
that I needed it in the past:

     public T probe() {
         Thread t = Thread.currentThread();
         ThreadLocalMap map = getMap(t);
         if (map != null) {
             ThreadLocalMap.Entry e = map.getEntry(this);
             if (e != null) {
                 T result = (T)e.value;
                 return result;
         return null;

Regards, Peter

More information about the core-libs-dev mailing list