Memory Leak Detection
A memory leak is an ownership failure: an object that should be unreachable remains connected to a GC root. Detection tools provide evidence, but the fix usually belongs in lifecycle or reference ownership.
LeakCanary and Memory Profiler
LeakCanary watches Android/JVM objects expected to become collectible, triggers heap analysis, and shows a reference chain to the retained object. It remains useful in Compose applications because Compose still runs on Android and the JVM. It is not a recomposition or layout profiler.
Android Studio Memory Profiler complements it with allocation recording, heap dumps, class-instance inspection, and manual comparison of memory behavior. Use it when growth is not tied to a lifecycle object or when allocation pressure matters more than one retained instance.
Heap dumps are snapshots. A retained object is not automatically a harmful leak: caches, framework behavior, debugger references, and work still in progress need context. The reference chain and expected lifecycle are decisive.
Typical sources
- an
ActivityorFragmentretained by a singleton; - listeners, callbacks, observers, or SDK registrations not removed;
- coroutine scopes that outlive their owner;
- Fragment View binding retained after
onDestroyView(); - long-lived references to
ActivityContext; - custom Views, adapters, or drawables holding a screen;
- unbounded caches and queues.
Investigation workflow
- Reproduce the same open/close or rotation scenario.
- Confirm that the object stays retained after expected cleanup.
- Inspect the shortest useful path from a GC root.
- Identify which component should own the reference.
- Fix ownership, scope, unregistering, or cleanup.
- Repeat the scenario and check memory behavior again.
Avoid treating WeakReference as the default fix. It can hide unclear ownership while introducing disappearing data. Prefer correcting the lifecycle boundary.