Skip to content

Conversation

mrdziuban
Copy link
Contributor

Fixes sbt/sbt#8142

This updates SbtUpdateReport.caching to use weak references for both the cached keys and values to prevent memory leaks.

Keys

Weak references to keys are handled by using a WeakHashMap instead of a ConcurrentHashMap.

Note that this also required passing the map to Collections.synchronizedMap to ensure it's still thread-safe. I'm guessing that a goal of sbt-coursier is to include as few dependencies as possible, but if that's not correct then I think it's likely that a better alternative to Collections.synchronizedMap would be to use one of:

  1. Guava's MapMaker class with calls to weakKeys and weakValues
  2. A Caffeine cache with calls to weakKeys and weakValues

Values

Weak references to values are handled by wrapping each value in WeakReference.

Results

Using https://github.com/mrdziuban/sbt-update-memory-leak, I ran:

./run.sh 500
./run.sh 1000
./run.sh 2000

and got the following results for the heap retained by SbtUpdateReport$:

Number of updates Retained heap
500 238,664 bytes
1000 298,520 bytes
2000 158,936 bytes

Copy link
Collaborator

@eed3si9n eed3si9n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@eed3si9n eed3si9n merged commit 34d2ac3 into coursier:main May 29, 2025
9 checks passed
@mrdziuban mrdziuban deleted the weak-hash-map branch May 30, 2025 15:34
@xuwei-k
Copy link
Contributor

xuwei-k commented Jun 2, 2025

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 update task, retained heap of lmcoursier.internal.SbtUpdateReport$ grows linearly
3 participants