Promptly freeing the per-thread cached direct buffers when a thread exits
David Holmes
david.holmes at oracle.com
Mon Apr 9 08:33:30 UTC 2018
Hi Peter,
On 9/04/2018 5:50 PM, Peter Levart wrote:
>
>
> On 04/09/18 08:25, David Holmes wrote:
>>
>>
>> On 7/04/2018 3:11 AM, Tony Printezis wrote:
>>> —————
>>> Tony Printezis | @TonyPrintezis | tprintezis at twitter.com
>>>
>>>
>>> On April 6, 2018 at 12:16:10 PM, David Lloyd (david.lloyd at redhat.com)
>>> wrote:
>>>
>>> On Fri, Apr 6, 2018 at 8:57 AM, Tony Printezis <tprintezis at twitter.com>
>>> wrote:
>>>>> ThreadLocal clearing
>>>>
>>>> Could you clarify what you mean by ThreadLocal clearing?
>>>
>>> I mean calling ThreadLocal#remove().
>>>
>>>
>>> I see. So, anyone who subclasses ThreadLocal can override remove().
>>> And if
>>> remove() is called by Thread::exit, it can be used as an exit hook.
>>> (David
>>> Holmes, if this is what you meant in your e-mail: apologies; I
>>> misunderstood.)
>>
>> Absolutely! ... Well kind of ... okay actually no, I wasn't thinking
>> at that level of detail yet. ;-)
>>
>> Cheers,
>> David H.
>
> There's no need in calling ThreadLocal.remove() at thread exit as
> Thread.exit() method already does that (sort of):
>
> private void exit() {
> ...
> threadLocals = null;
> inheritableThreadLocals = null;
> ...
>
> After thread exits, ThreadLocal values associated with it are no longer
> reachable from its Thread object.
>
> The problem Tony faces is that by the time this happens, direct
> ByteBuffer's that were cached using such ThreadLocal value, are already
> moved to old GC generation, waiting for full GC to release them together
> with direct memory they are holding.
Right. So the suggestion was to call ThreadLocal.remove() instead (as
well as?) so that you could define a custom ThreadLocal class for the
buffers that override remove() to actually release the buffer directly.
David
-----
> So what is needed is an internal call-back registration API Alan is
> proposing and (maybe just internal) probing method for ThreadLocal that
> return(s) the associated value only when it has already been initialized.
>
> Regards, Peter
>
>>
>>>
>>>
>>>
>>>> I like the suggestion to add an overridable exit() method to
>>>> ThreadLocal.
>>> If
>>>> you want to avoid calling user code by Thread::exit, would adding
>>>> ThreadLocals (which are tagged appropriately) to a queue for later
>>>> processing a better approach (similar to the mechanism used for
>>> References /
>>>> ReferencesQueues)? The user can of course create a memory leak by not
>>>> polling the queue frequently enough. But, that’s also the case for
>>>> References. And at least user code cannot block Thread::exit.
>>>
>>> It's more complexity, and at some point you have to ask: is it better
>>> to block thread A or thread B? At least blocking thread A is somewhat
>>> expected.
>>>
>>>
>>> I agree re: it’d add complexity. #simplify :-)
>>>
>>> Tony
>>>
>>>
>>>
>
More information about the core-libs-dev
mailing list