*`Modifier.dropShadow` keeps a bitmap for every si...
# compose-android
m
Modifier.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.
👀 7