Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coil Bitmap cache trimming behavior is suboptimal #2923

Open
shaybarak opened this issue Apr 1, 2025 · 3 comments
Open

Coil Bitmap cache trimming behavior is suboptimal #2923

shaybarak opened this issue Apr 1, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@shaybarak
Copy link

Coil registers for onTrimMemory and has different trim handlers that will reduce the cache size or entirely clear it. Great! This in theory allows apps that use Coil to use less memory, especially when they don't need as much memory for caching Bitmaps.

Unfortunately, Coil's strategy is incomplete and partially relies on deprecated platform behavior.

Coil responds to TRIM_MEMORY_BACKGROUND to clear the cache (great!), and responds to TRIM_MEMORY_RUNNING_LOW to trim the cache to half its size. There are two problems with the latter:

  1. TRIM_MEMORY_RUNNING_LOW is deprecated. Apps are not notified of this level since Android API 34.
  2. Trimming is temporary - Coil will discard the oldest entries to immediately reduce the cache size, but the cache is allowed to grow back to its previous max size over time.

For reference please refer to Glide's LruBitmapPool. Glide will:

  1. Clear memory caches on TRIM_MEMORY_BACKGROUND (same as Coil).
  2. Trim half of the memory caches on TRIM_MEMORY_UI_HIDDEN, and adjust the cache max size so it's reduced.

After receiving TRIM_MEMORY_UI_HIDDEN, the app knows that it's not showing a UI so it doesn't need to be able to handle a lot of Bitmaps on the screen or fast UI scrolls such as fling gestures. A typical use case of an app having its UI hidden but still working with Bitmaps is for instance a media player that is going from a foreground player UI to a media playback service while the user is multitasking. In the latter case, the Bitmap cache can be very small at no loss of app performance.

Thank you for considering this issue.

@shaybarak shaybarak added the enhancement New feature or request label Apr 1, 2025
@colinrtwhite
Copy link
Member

colinrtwhite commented Apr 5, 2025

Trim half of the memory caches on TRIM_MEMORY_UI_HIDDEN, and adjust the cache max size so it's reduced.

@shaybarak Can you link to the code that does this? From what I can tell Glide's memory cache trims the cache size to 1/2 on TRIM_MEMORY_UI_HIDDEN, but does not reduce the max size. Also when does it increase the cache's max size back to the original size?

LruBitmapPool serves a different function than Coil/Glide's MemoryCache. It does not cache images - instead it holds an object pool of bitmaps that can be re-drawn on.

Overall, I'm not sold on Glide's behaviour of clearing half the memory cache on TRIM_MEMORY_UI_HIDDEN as it feels a bit arbitrary. Why only clear half and not just clear the cache completely? It's unfortunate that Android removed events for apps to respond to memory pressure as those used to be much more effective for figuring out when to free up memory in the foreground or background vs. naively clearing memory when entering the background. However, clearing the memory cache in TRIM_MEMORY_UI_HIDDEN won't really help as TRIM_MEMORY_BACKGROUND will still be called before the app is evicted.

@shaybarak
Copy link
Author

@colinrtwhite you're right, it looks like Glide doesn't change the max cache size on trim events (though I'd argue maybe it should).
I think we're in agreement that Glide's response to trim events is arbitrary. The same can be said perhaps about the default sizes and the multipliers offered to setMemoryCategory.

Rather than try to emulate Glide, perhaps we could develop a superior cache trimming strategy?

@colinrtwhite
Copy link
Member

@shaybarak What is your suggestion? Without a way to observe memory pressure events on API >= 34 I don't think there much we can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants