Memory Leaks You Probably Missed in Jetpack Compose
Article Summary
Mahmut Yuce from Getir destroys the myth that declarative UI means no memory leaks. Compose apps leak differently, and these patterns are sneakier than the old View system bugs.
This deep dive reveals five production-level memory leak patterns in Jetpack Compose that slip past most code reviews. Yuce walks through real scenarios mixing Compose with Fragments, coroutines, and native resources, showing exactly how long-lived objects create invisible reference chains that keep entire UI graphs alive.
Key Takeaways
- ComposeView in Fragments leaks without ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
- MediaPlayer and SDK clients in remember() hold Context references indefinitely
- rememberSaveable with Bitmaps serializes heavy objects into saved state bundles
- GlobalScope.launch inside LaunchedEffect keeps collectors running after composition exits
- WebView in AndroidView needs explicit destroy() or it retains Context and caches
Compose reduces adapter leaks but introduces new patterns around lifecycle mismatches, especially when mixing Views, coroutines, and native resources that outlive composition.
About This Article
Mahmut Yuce found that Fragment and ComposeView patterns can hold onto old Activity instances and entire composition trees when bindings aren't cleared in onDestroyView. This causes memory leaks during configuration changes and navigation cycles, where full UI graphs stick around indefinitely.
Use nullable binding fields and clear them in onDestroyView. Also apply ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed to ComposeView so the composition lifetime is tied directly to when the Fragment View gets destroyed.
Developers get a concrete checklist to prevent hidden reference chains like CheckoutViewModel pointing to navController pointing to Activity pointing to Window pointing to ViewTree pointing to ComposeView pointing to Composition. These chains leak entire screens after navigation.