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