Was there a reason why this was not introduced in the first place? Tony
————— Tony Printezis | @TonyPrintezis | tprinte...@twitter.com On April 6, 2018 at 8:49:17 AM, Peter Levart (peter.lev...@gmail.com) wrote: 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) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return null; } Regards, Peter