Hi David,

ThreadLocals getting cleared is not enough. The threadLocals field is
cleared by Thread::exit:

    private void exit() {
        ...
        threadLocals = null;
        ...
    }

but this doesn’t really do anything. The GC has to run, find the direct
buffer in the ThreadLocal unreachable, and queue its Cleaner for
processing. I’m looking for a hook to explicitly reclaim the direct buffer
when Thread::exit is called.

Tony

—————
Tony Printezis | @TonyPrintezis | tprinte...@twitter.com


On April 5, 2018 at 6:07:26 PM, David Holmes (david.hol...@oracle.com)
wrote:

Hi Tony,

On 6/04/2018 7:45 AM, 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

If it's in a ThreadLocal then aren't you just asking for thread-locals
to be cleared at thread exit?

Cheers,
David

> 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.
>
> Interestingly, the service in question does concurrent GC cycles really
> infrequently (one every few days) as it has a really low promotion rate.
> This results in the JVM's total direct size constantly increasing (which
is
> effectively a native buffer leak).
>
> Has anyone come across this issue before?
>
> There are a few obvious ways to mitigate this, e.g., cause a Full GC /
> concurrent GC cycle at regular intervals. However, the best solution IMHO
> is to explicitly free any direct buffers that are still in the cache when
a
> thread exits.
>
> I'll be happy to implement this and test it internally at Twitter, if
it's
> not on anyone else's radar. However, to do what I'm proposing I need some
> sort of thread exit hook. Unfortunately, there doesn't seem to be one.
>
> Would proposing to introduce thread exit hooks be reasonable? Or is
> everyone going to freak out? :-) The hooks can be either per-Thread or
even
> per-ThreadLocal. And it's OK if the hooks can only be used within
java.base.
>
> FWIW, I did a simple prototype of this (I call the hooks from
Thread::exit)
> and it seems to work as expected.
>
> Any thoughts / feedback on this will be very appreciated.
>
> Thanks,
>
> Tony
>
>
>
> —————
> Tony Printezis | @TonyPrintezis | tprinte...@twitter.com
>

Reply via email to