Mark
10/08/2026, 11:29 AMModifier.dropShadow keeps a bitmap for every size/radius it's ever drawn at, until the app goes to the background
I hit a large native-memory leak in an image reader and traced it to the drop-shadow renderer cache (Compose UI 1.12.1, Android).
AndroidShadowContext.obtainDropShadowRenderer keys its cache on shape, size, layout direction, density and the whole Shadow (radius included). Every new key renders a fresh Alpha8 bitmap the size of the shape plus the blur. Nothing evicts entries: the cache is only cleared in AndroidGraphicsContext on onTrimMemory(>= TRIM_MEMORY_BACKGROUND) or when the view detaches. So anything whose size or radius changes per frame adds a bitmap per frame for as long as the app stays in the foreground:
• a dropShadow on something with animateContentSize, or resized by a drag
• a radius that follows a zoom, e.g. Shadow(radius = 6.dp / userScale) to keep it constant on screen
Measured (dumpsys meminfo, "Bitmap (malloced)"):
• minimal repro, an animated dropShadow radius on a 300dp box: 0 → ~650 bitmaps (128 MB) in 30 s; the same animation without the shadow: none
• 9 drags resizing a bottom panel (Pixel 7a): +282 bitmaps, +232 MB
• ~10 s of pinch-zooming a photo with a zoom-scaled shadow radius: +839 bitmaps, +792 MB
• backgrounding the app (trim → cache cleared) and forcing a GC: back down to almost nothing
Root cause, repro and numbers: issuetracker.google.com/issues/507490551#…
Workaround: I replaced the shadows with outlines drawn in drawWithContent / drawBehind, which allocate nothing per frame. Or keep dropShadow only on things whose size and radius stay fixed.
Is an unbounded cache intended here? An LRU limit, or dropping a renderer once no painter uses its key, would fix it.