Garbage collection on Android

Runtime, build and Gradle Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Spot the bug

Which line allocates on every frame?

  1. class Gauge(context: android.content.Context) : android.view.View(context) {
  2. private val paint = android.graphics.Paint()
  3. var value = 0f
  4. override fun onDraw(canvas: android.graphics.Canvas) {
  5. val rect = android.graphics.RectF(0f, 0f, width * value, height.toFloat())
  6. canvas.drawRect(rect, paint)
  7. }
  8. }
Hint 1 of 1

Which object is created inside onDraw?

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

Show answer
  • Answer: line 5 val rect = android.graphics.RectF(0f, 0f, width * value, height.toFloat())

Line 5 creates a new RectF every time onDraw runs, which can be 60 or more times a second. Keep one RectF as a field and update it with set().

30-second answer

ART frees objects that are no longer reachable from GC roots such as threads, static fields and JNI references. Modern ART uses a concurrent, generational collector, so pauses are short, but allocating lots of short-lived objects in hot paths (onDraw, scroll, tight loops) still costs CPU and can cause jank. Leaks happen when a long-lived root keeps something like an Activity reachable.

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

Explain garbage collection.

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

  • Reachability from GC roots
  • Concurrent, generational ART GC
  • Allocation churn costs frames
  • Leaks are reachable objects

Deep dive

A GC root reference chain is what LeakCanary prints.

Avoid allocations in onDraw and per-frame code.

onTrimMemory tells you to release caches under pressure.

The low memory killer stops whole processes; GC can't save a process that holds too much.

Common mistakes

  • Calling System.gc().
  • Allocating objects in onDraw.
  • Thinking Kotlin or GC prevents leaks.

Senior take & follow-ups

Explain reachability, then link GC to leaks and jank.

Follow-up questions

Think of your answer first, then open the hint.

  1. What is a GC root?

    Show hint

    A starting point such as a thread stack, static field or JNI ref.

  2. Why does allocation churn matter if pauses are short?

    Show hint

    Collection still uses CPU time that frames need.

Similar on iOS: How ARC works iOS uses reference counting instead of a tracing garbage collector.

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