LeakCanary — wat is het, bibliotheek voor het vinden van lekken in Android

Auteur: IT Sectr Gepubliceerd: 2026-03-30 Leestijd: 9 min

LeakCanary — is een open source bibliotheek van Square voor automatische detectie van geheugenlekken in Android-applicaties. Het integreert in het ontwikkelproces en volgt in realtime de levenscyclus van Activity, Fragment, ViewModel en andere componenten, waarbij het lekken direct na hun optreden signaleert. Volgens gegevens van Square Open Source, wordt de bibliotheek gebruikt in duizenden projecten en wordt het beschouwd als de de facto standaard voor geheugendiagnostiek op Android.

Belangrijkste punten

  • LeakCanary — bibliotheek voor automatische detectie van geheugenlekken op Android.
  • Werkingsmechanisme is gebaseerd op WeakReference en handmatig starten van GC na vernietiging van de component.
  • Heap dump wordt automatisch aangemaakt bij detectie van een lek en geanalyseerd door de ingebouwde analyzer.
  • Resultaat — een exacte keten van referenties (leak trace) die de locatie van het lek in de code aangeeft.
  • LeakCanary 2.x vereist geen handmatige configuratie — één afhankelijkheid in build.gradle is voldoende.

Wat is LeakCanary?

LeakCanary — is een bibliotheek voor automatische detectie van geheugenlekken in Android-applicaties, ontwikkeld door Square. Het wordt ingebed in het buildproces van de applicatie en volgt automatisch wanneer objecten die vernietigd zouden moeten worden (Activity, Fragment, View) in het geheugen blijven. Bij detectie van een lek maakt LeakCanary een heap dump en analyseert de keten van referenties die het object vasthoudt.

De bibliotheek is een standaard geworden in de Android-gemeenschap: volgens GitHub heeft het project meer dan 28.000 sterren verzameld en wordt het gebruikt in applicaties van Google, Uber, Airbnb en Facebook. LeakCanary is beschikbaar in twee hoofdversies: klassiek 1.x (met handmatige configuratie) en modern 2.x (automatische integratie via ContentProvider). Versie 2.x vereist geen wijziging van de Application-klasse — één afhankelijkheid is voldoende voor volledige werking.

De belangrijkste taak van LeakCanary is het detecteren van situaties waarin een object in het geheugen blijft bestaan nadat zijn levenscyclus is voltooid. Dit is typisch voor lekken via statische velden, singletons, niet-geregistreerde callbacks, anonieme klassen en closures die externe objecten vastleggen.

Waarom LeakCanary belangrijk is voor Android-ontwikkeling

Geheugenlekken op Android zijn kritieker dan op desktop vanwege de beperkte hoeveelheid RAM op mobiele apparaten. Zelfs een lek van 5–10 MB bij elke schermovergang kan leiden tot OutOfMemoryError na 30–40 minuten gebruik van de applicatie. LeakCanary detecteert dergelijke problemen in de ontwikkelingsfase, zonder te wachten op een crash in productie.

Hoe werkt LeakCanary?

LeakCanary gebruikt zwakke referenties (WeakReference) in combinatie met geforceerde aanroep van de garbage collector. Wanneer Activity of Fragment onDestroy aanroept, maakt LeakCanary een WeakReference naar dit object en start GC na een korte vertraging (standaard 5 seconden). Als het object na GC nog steeds toegankelijk is via WeakReference, betekent dit dat het wordt vastgehouden door een sterke referentie — er wordt een lek geregistreerd.

Na detectie van een lek maakt LeakCanary een heap dump (volledige momentopname van het applicatiegeheugen in HPROF-formaat). Vervolgens bouwt de ingebouwde analyzer (Shark voor versie 2.x) een bereikbaarheidsgraf van GC Roots naar het gelekte object en vindt het kortste pad — de keten van referenties die het object in het geheugen vasthoudt.

kotlin
// Vereenvoudigde detectielogica van LeakCanary
class ObjectWatcher {
    private val watchedReferences = CopyOnWriteArrayList<KeyedWeakReference>()

    fun watch(watchedObject: Any, description: String) {
        val reference = KeyedWeakReference(watchedObject, description)
        watchedReferences.add(reference)
        BackgroundHandler.postDelayed({
            checkForLeaks()
        }, 5000)
    }

    private fun checkForLeaks() {
        GcTrigger.runGc() // geforceerde GC
        for (ref in watchedReferences) {
            if (ref.get() != null) {
                onLeakFound(ref) // object heeft GC overleefd — dit is een lek
            }
        }
    }
}

Het belangrijkste punt — de geforceerde aanroep van GcTrigger.runGc(). Zonder dit is het onmogelijk om een werkelijk gelekt object te onderscheiden van een object dat GC nog niet heeft kunnen verzamelen. LeakCanary doet dit tot drie keer: als na drie GC-cycli het object nog steeds in het geheugen is — wordt het lek bevestigd.

Wat is Shark — heap dump analyzer

Shark — is de ingebouwde heap dump analyzer in LeakCanary 2.x, geschreven in Kotlin. In tegenstelling tot de vorige analyzer HAHA, laadt Shark niet het hele HPROF-bestand in het geheugen, maar doorloopt het de objectengraf met minimale allocaties. Dit vermindert het RAM-verbruik tijdens analyse van 50 MB naar 2–5 MB en verkort de analysetijd van 30 seconden naar 1–3 seconden.

Hoe installeer en configureer je LeakCanary?

Installatie van LeakCanary 2.x in een modern Android-project duurt één regel in build.gradle. De bibliotheek gebruikt ContentProvider voor automatische initialisatie — je hoeft de Application-klasse niet aan te passen of code aan MainActivity toe te voegen. De verbinding wordt alleen voor debug-build gemaakt, zodat er geen overbodige code in de release APK zit.

groovy
// build.gradle (app/module)
dependencies {
    // debugImplementation — bibliotheek alleen voor debug-build
    debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
}

Na het toevoegen van de afhankelijkheid en herbouwen van het project verschijnt LeakCanary automatisch in de applicatie. Bij de eerste start toont de bibliotheek een systeemmelding over activering. Alle gedetecteerde lekken worden weergegeven als meldingen — klik op de melding opent het scherm met het gedetailleerde rapport (LeakTrace).

Voor aanpassing kun je je eigen AppWatcherInstaller maken en parameters overschrijven: GC-timeout, lijst van gevolgde objecttypen, inschakelen van het opslaan van heap dump op schijf. Voor 90% van de projecten is de standaardconfiguratie echter optimaal.

Configuratie voor coroutines en Jetpack Compose

Vanaf versie 2.12 ondersteunt LeakCanary automatische tracking van ViewModel, coroutine-scopes en State-objecten van Compose. Extra afhankelijkheden zijn niet vereist — de bibliotheek detecteert zelf welke Jetpack-componenten in het project worden gebruikt en activeert de bijbehorende detectoren.

Hoe lees je een LeakCanary-rapport

Het LeakCanary-rapport (LeakTrace) — is een meerregelige keten van referenties van GC Root naar het gelekte object. Elke regel toont de klasse en het veld waardoor de sterke referentie loopt. De ontwikkelaar moet de keten van onder naar boven lezen: onderste regel — gelekt object, bovenste — ingangspunt (GC Root).

Een typische LeakTrace ziet er zo uit: GC Root → statisch veld Application → singleton → callback → Activity. Als een ontwikkelaar zo'n keten ziet, is het probleem duidelijk: de singleton houdt een callback vast die een referentie naar Activity heeft vastgelegd. Oplossing — vervang de sterke referentie door een zwakke in de singleton.

text
┬
├─ android.app.Application
│    Leaking: NO (Application — singleton)
│    ↓ Application.leakedActivities
├─ java.util.ArrayList
│    Leaking: NO (ArrayList — normal)
│    ↓ ArrayList[0]
├─ com.example.MainActivity
│    Leaking: YES (Activity destroyed but still in memory)
│    ↓ MainActivity.mCallback
├─ com.example.CallbackWrapper
│    Leaking: UNKNOWN
│    ↓ CallbackWrapper.mListener
│              ~~~~~~~~~~
├─ com.example.MyCallback (anonymous)
│    Leaking: UNKNOWN
│    ↓ MyCallback.this$0
├─ com.example.MainActivity
│    Leaking: YES (MainActivity is the leak)
╰

In dit voorbeeld laat LeakCanary zien dat MainActivity wordt vastgehouden via de keten: Application → ArrayList → MainActivity → CallbackWrapper → MyCallback → weer MainActivity. De pijl this$0 geeft aan dat de anonieme klasse MyCallback een externe referentie naar Activity heeft vastgelegd. Oplossing — maak de callback een zwakke referentie of annuleer deze in onDestroy.

LeakCanary toont ook de lekstatus voor elk element van de keten: NO (geen lek — dit is het root-element), YES (object moet worden vernietigd), UNKNOWN (status kon niet worden bepaald). Status UNKNOWN betekent geen probleem — het is een tussenliggend object dat LeakCanary niet eenduidig kan classificeren.

LeakCanary 2.x vs 1.x: belangrijkste verschillen

De overgang van versie 1.x naar 2.x was ingrijpend: ontwikkelaars hebben de bibliotheek helemaal herschreven, waarbij de verouderde HAHA-analyzer werd vervangen door een eigen motor Shark geschreven in Kotlin. Shark werkt aanzienlijk sneller, vereist minder geheugen voor analyse en bepaalt nauwkeuriger de hoofdoorzaken van lekken.

ParameterLeakCanary 1.xLeakCanary 2.x
AnalyzertaalJava (HAHA — fork van Android SDK)Kotlin (Shark — eigen motor)
InstallatieHandmatige configuratie van AppWatcher in ApplicationAutomatisch via ContentProvider
Snelheid10–30 seconden voor heap dump analyse1–5 seconden voor heap dump analyse
PrestatiesNeemt 10–50 MB RAM in tijdens analyseNeemt 2–10 MB RAM in tijdens analyse

Het belangrijkste voordeel van Shark — het laadt niet de hele heap dump in het geheugen, maar doorloopt de referentiegraf met minimale allocaties. Dit maakt LeakCanary 2.x geschikt voor gebruik op apparaten met weinig RAM zonder risico op OutOfMemoryError tijdens analyse.

In versie 2.x is ook de mogelijkheid toegevoegd om heap dump te exporteren naar een bestand voor latere analyse in Android Studio Memory Profiler. Hiervoor moet je de instelling dumpHeapWhenLeakFound inschakelen in de configuratie van AppWatcher.

Typische lekken gevonden door LeakCanary

LeakCanary detecteert effectief verschillende klassen van lekken die kenmerkend zijn voor Android. Het meest voorkomend is een lek via statische referenties naar Activity — ontwikkelaars bewaren een referentie naar de Activity-context in een singleton, en Activity kan niet door GC worden verzameld na voltooiing van zijn levenscyclus.

De tweede meest voorkomende categorie — lekken via niet-geregistreerde listeners. Als in onStart registerListener is aangeroepen, maar in onStop/onDestroy geen unregisterListener is aangeroepen — wordt het listener-object door het systeem vastgehouden, zelfs na vernietiging van de activiteit. LeakCanary laat ondubbelzinnig zien welke listener en in welke systeemdienst actief is gebleven.

kotlin
// Typisch lek: Activity vastgelegd in callback van singleton
object AnalyticsManager {
    private var callback: ((String) -> Unit)? = null

    fun register(callback: (String) -> Unit) {
        this.callback = callback // sterke referentie naar callback
    }

    fun unregister() {
        callback = null // VERGEET NIET aan te roepen in onDestroy!
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AnalyticsManager.register { event ->
            logEvent(event) // lambda legt this vast
        }
        // als je unregister niet aanroept in onDestroy → Activity-lek
    }
}

De derde categorie — lekken via Fragment in BackStack. Als FragmentTransaction.addToBackStack() wordt aangeroepen zonder Fragment te verwijderen bij terugkeer, blijven oude Fragment-instanties in het geheugen. LeakCanary helpt dergelijke verborgen lekken in een vroeg stadium van de ontwikkeling te ontdekken.

Voor elk gedetecteerd lek biedt LeakCanary een beschrijving en aanbevelingen voor reparatie. In versie 2.14 is integratie met Android Lint toegevoegd — de bibliotheek kan automatisch taken aanmaken in de issue tracker bij detectie van een lek in CI.

Veelgestelde vragen

Moet LeakCanary worden verwijderd uit de release APK?

Ja, absoluut. LeakCanary wordt aangesloten via debugImplementation in build.gradle, wat het automatisch uitsluit van de release-build. Als je het via implementation aansluit, komt de bibliotheek in de release APK en zal het lekken tonen aan eindgebruikers — dit is onaanvaardbaar.

Vertraagt LeakCanary de werking van de applicatie?

De impact op prestaties is minimaal. LeakCanary wordt alleen geactiveerd na onDestroy van de component en bemoeit zich niet met het renderen van UI of het verwerken van aanrakingen. De enige kosten — een korte pauze van geforceerde GC (ongeveer 100 ms) en het schrijven van heap dump bij een lek (honderdsten van een seconde).

Hoe exporteer ik een LeakCanary-rapport?

LeakCanary slaat automatisch de heap dump op in HPROF-formaat in de applicatiemap. Het bestand kan worden geëxporteerd via Android Studio: Device File Explorer → data/data/com.example/files/leakcanary/. Om te bekijken, open je het bestand in Memory Profiler via Capture → Open Heap Dump.

Werkt LeakCanary met Jetpack Compose?

Ja, vanaf versie 2.12 ondersteunt LeakCanary volledig Jetpack Compose. De bibliotheek volgt Composition-contexten en State-objecten, en detecteert automatisch lekken in Composable-functies. Aparte configuratie is niet nodig — het werkt uit de doos.

Kan LeakCanary fout-positieven geven (false positive)?

Vals-positieve meldingen zijn mogelijk, maar zeldzaam. LeakCanary gebruikt een drievoudige GC-aanroep voordat een lek wordt verklaard, wat de meeste valse positieven elimineert. Als je denkt dat een melding vals is — maak dan een IgnoredReference voor de specifieke klasse in de configuratie.

Samenvatting

  • LeakCanary — standaardbibliotheek voor automatische detectie van geheugenlekken in Android-applicaties.
  • De bibliotheek gebruikt WeakReference en geforceerde GC voor detectie van objecten die hun levenscyclus hebben overleefd.
  • Heap dump wordt geanalyseerd door de ingebouwde Shark-motor, die een referentieketen bouwt van GC Root naar het gelekte object.
  • Installatie in een modern project — één regel in build.gradle: debugImplementation.
  • LeakCanary 2.x is volledig herschreven in Kotlin en werkt 5–10 keer sneller dan de vorige versie.
  • Meest voorkomende lekken: statische referenties naar Activity, niet-geregistreerde listeners en Fragment in BackStack.
  • Implementeer LeakCanary in de debug-build van elk project — dit voorkomt lekken in productie.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook