Skip to content

fix: CacheManager memory leak by reusing InheritableThreadLocal (#6730)#6732

Closed
mmustafasenoglu wants to merge 1 commit into
apache:masterfrom
mmustafasenoglu:fix/cachemanager-inheritablethreadlocal-leak
Closed

fix: CacheManager memory leak by reusing InheritableThreadLocal (#6730)#6732
mmustafasenoglu wants to merge 1 commit into
apache:masterfrom
mmustafasenoglu:fix/cachemanager-inheritablethreadlocal-leak

Conversation

@mmustafasenoglu

Copy link
Copy Markdown

Summary

CacheManager.clearCache() creates a new InheritableThreadLocal instance on every call without calling .remove() on the previous one, causing a progressive memory leak that grows with iteration_count × thread_count when "Clear cache each iteration" is enabled.

The existing TODO in the code already acknowledged this:

// TODO: avoid re-creating the thread local every time, reset its contents instead

Fix

  • Initialize threadCache once at field declaration
  • Replace clearCache() body with threadCache.remove() instead of creating a new instance
  • The next .get() call lazily creates a fresh cache via initialValue()
  • Added @SuppressWarnings("ThreadLocalUsage") since InheritableThreadLocal is intentionally used for per-thread caching

Testing

All 80 CacheManager tests pass (0 failed, 1 skipped):

TestCacheManagerThreadIteration:      5/5  ✅
TestCacheManagerHC4:                 50/50 ✅
TestCacheManagerUrlConnection:       25/25 ✅

Fixes #6730

CacheManager.clearCache() was creating a new InheritableThreadLocal
instance on every call without calling .remove() on the previous one.
This caused a progressive memory leak that grows with
iteration_count x thread_count when 'Clear cache each iteration'
is enabled.

The existing TODO comment acknowledged this:
  // TODO: avoid re-creating the thread local every time,
  // reset its contents instead

Fix by initializing threadCache once at field declaration and calling
threadCache.remove() in clearCache() instead of creating a new
instance. The next .get() call will lazily create a fresh cache
via initialValue().

Also added @SuppressWarnings for ErrorProne's ThreadLocalUsage since
InheritableThreadLocal is used intentionally for per-thread caching.

Fixes apache#6730

Signed-off-by: Mustafa Senoglu <mmustafasenoglu0@gmail.com>
@vlsi

vlsi commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Closing as duplicate of #6731

@vlsi vlsi closed this Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory Leak in CacheManager: InheritableThreadLocal Recreated Without Cleanup on Every Iteration

2 participants