Optimise CleaningThreadLocal orphan cleanup by caching Thread.isAlive() results#842
Open
peter-lawrey wants to merge 1 commit into
Open
Optimise CleaningThreadLocal orphan cleanup by caching Thread.isAlive() results#842peter-lawrey wants to merge 1 commit into
CleaningThreadLocal orphan cleanup by caching Thread.isAlive() results#842peter-lawrey wants to merge 1 commit into
Conversation
|
CleaningThreadLocal orphan cleanup by caching Thread.isAlive() results
tgd
reviewed
Apr 28, 2026
| return true; | ||
|
|
||
| // cache isAlive results so it doesn't become O(N * M) on a costly operation. | ||
| Map<Thread, Boolean> isThreadAlive = new IdentityHashMap<>(); |
Contributor
There was a problem hiding this comment.
Does this cache need to be hoisted up a level?
tgd
requested changes
Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Reduce repeated
Thread.isAlive()calls duringCleaningThreadLocalorphan cleanup by caching liveness per thread for the duration of a cleanup pass.Problem
doCleanupNonCleaningThreads()iterates overnonCleaningThreadValues, where multiple entries can belong to the same thread. Before this change,Thread.isAlive()was called for every entry, which can turn cleanup into an effectiveO(n * m)repetition of a non-trivial/native operation when many values are associated with fewer threads.In practice this showed up as timeout pressure in tests, with stack traces spending significant time in
Thread.isAlive()during orphan tracking cleanup.Change
This change introduces a per-pass
IdentityHashMap<Thread, Boolean>to memoise thread liveness:isAlive()at most once perThreadduring a cleanup passUsing
IdentityHashMapkeeps the cache aligned with thread identity semantics.Why
This improves efficiency by:
isAlive()callsBehavioural impact
No intended functional change.
The cleanup logic is unchanged; this is a performance optimisation within a single cleanup pass.
Motivation
This change is motivated by observed timeout failures such as:
TestTimedOutException: test timed out after 60 secondsjava.lang.Thread.isAlive(...)CleaningThreadLocal.doCleanupNonCleaningThreads(...)Implementation notes
computeIfAbsentExpected outcome
More predictable orphan-tracking cleanup performance, especially in cases where many tracked values reference the same set of threads.