Memory leaks

Performance Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Spot the bug

LeakCanary reports MainActivity leaked through AnalyticsTracker.listener. Which line causes it?

  1. object AnalyticsTracker {
  2. var listener: (() -> Unit)? = null
  3. }
  4. ​
  5. class MainActivity : ComponentActivity() {
  6. override fun onCreate(savedInstanceState: Bundle?) {
  7. super.onCreate(savedInstanceState)
  8. AnalyticsTracker.listener = { title = "Synced" }
  9. }
  10. }
Hint 1 of 1

What does the lambda capture?

Choose an answer, then open Show answer below to check it.

Show answer
  • Answer: line 8 AnalyticsTracker.listener = { title = "Synced" }

The lambda captures the Activity (it touches title) and the singleton keeps it forever. Clear the listener in onDestroy, or expose a Flow the Activity collects with its lifecycle.

30-second answer

A leak happens when something long-lived keeps a reference to something that should have been freed, usually an Activity, Fragment view or Context. Typical causes: a singleton or static field holding an Activity, listeners not unregistered, coroutines or callbacks that capture a view and outlive it, and Fragment bindings kept after onDestroyView. LeakCanary finds them automatically in debug builds with the reference chain.

Practise saying it · 35 s. No recording, just a timer

Explain common leaks and tools.

Say your answer out loud, then check which of these points you covered:

  • Long-lived object holds a short-lived one
  • Singletons, listeners, captured views
  • LeakCanary reference chains
  • Use app context and lifecycle scopes

Deep dive

The Memory Profiler's heap dump shows retained instances; filter by Activity.

Use the application context for long-lived objects.

Scope work to lifecycles: viewModelScope, viewLifecycleOwner, DisposableEffect.

Leaks cause out-of-memory crashes and more GC, which also causes jank.

Common mistakes

  • Storing an Activity Context in a singleton.
  • Registering listeners without unregistering.
  • Keeping Fragment bindings after onDestroyView.

Senior take & follow-ups

List causes with fixes, and mention LeakCanary's reference chain.

Follow-up questions

Think of your answer first, then open the hint.

  1. What does LeakCanary report?

    Show hint

    The chain of references from a GC root to the leaked object.

  2. Which Context is safe in a singleton?

    Show hint

    The application context.

Similar on iOS: Retain cycles and how to break them iOS leaks come from reference cycles under ARC; Android leaks come from long-lived references the GC can't free.

Suggest a fix if something here is wrong or out of date.