LeakCanary ObjectWatcher Deep Dive - The Silent Guardian of Memory

 


Introduction

In Part 1, we saw how LeakCanary detects leaks at a high level. But the real magic begins with ObjectWatcher — the component that quietly observes destroyed objects and decides whether they’re truly gone or suspiciously retained.

Understanding ObjectWatcher is crucial if you want to debug leaks beyond surface level and explain them with authority.

🧩 What is ObjectWatcher?

ObjectWatcher is a core utility inside LeakCanary that:

  • Tracks destroyed objects (Activities, Fragments, Views, ViewModels).
  • Holds them via weak references.
  • Periodically checks if they’ve been garbage collected.
  • Flags them as retained if they’re still alive after GC.

Think of it as a security guard: once an object leaves the building (destroyed), ObjectWatcher ensures it doesn’t sneak back in.

⚙️ How ObjectWatcher Works

1. Watching Objects

objectWatcher.watch(
destroyedActivity,
"Activity was destroyed but not GC'd"
)
  • LeakCanary calls watch() whenever a lifecycle event signals destruction.
  • The object is wrapped in a WeakReference.
  • A KeyedWeakReference is stored in a ReferenceQueue.

2. Reference Queue Check

  • The ReferenceQueue is polled after a delay.
  • If the weak reference hasn’t been cleared, it means the object is still retained.
  • ObjectWatcher then marks it as suspicious.

3. Triggering Heap Dump

  • If enough retained objects accumulate, LeakCanary triggers a heap dump.
  • Shark then analyzes the dump to confirm whether it’s a real leak.

📊 Diagram: ObjectWatcher Flow

Destroyed Object → WeakReference → ReferenceQueue → GC Check → Retained? → Heap Dump → Shark Analysis

🧑‍💻 Example: Manual Watching

You can also manually watch custom objects:

val presenter = MyPresenter()
objectWatcher.watch(presenter, "Presenter should be cleared")

This is powerful for non‑lifecycle objects like presenters, managers, or detached views.

🚨 Why ObjectWatcher Matters

  • Early detection: Finds leaks before they crash your app.
  • Custom flexibility: Lets you watch any object, not just Activities.
  • Foundation for Shark: Without ObjectWatcher, Shark wouldn’t know what to analyze.

🔮 Coming Next

In Part 3, we’ll explore Heap Dumping Explained — how LeakCanary freezes your app, writes a .hprof file, and why that trade‑off is worth it.


If you found this useful, connect with me on Twitter/X and LinkedIn. I write about Kotlin, Android architecture, and multiplatform development.

Comments