LeakCanary — co to je, knihovna pro hledání úniků v Androidu

Autor: IT Sectr Publikováno: 2026-03-30 Doba čtení: 9 min

LeakCanary — je open source knihovna od Square pro automatickou detekci úniků paměti v Android aplikacích. Integruje se do vývojového procesu a v reálném čase sleduje životní cyklus Activity, Fragment, ViewModel a dalších komponent, signalizuje úniky ihned po jejich vzniku. Podle údajů Square Open Source je knihovna používána v tisících projektů a je považována za de facto standard pro diagnostiku paměti na Androidu.

Hlavní body

  • LeakCanary — knihovna pro automatickou detekci úniků paměti na Androidu.
  • Mechanismus práce je založen na WeakReference a ručním spuštění GC po zničení komponenty.
  • Heap dump je vytvořen automaticky při detekci úniku a analyzován vestavěným analyzátorem.
  • Výsledek — přesný řetězec referencí (leak trace) ukazující místo úniku v kódu.
  • LeakCanary 2.x nevyžaduje ruční konfiguraci — stačí jedna závislost v build.gradle.

Co je LeakCanary?

LeakCanary — je knihovna pro automatickou detekci úniků paměti v Android aplikacích, vyvinutá společností Square. Je vložena do procesu sestavování aplikace a automaticky sleduje, když objekty, které by měly být zničeny (Activity, Fragment, View), zůstávají v paměti. Při detekci úniku LeakCanary vytvoří heap dump a analyzuje řetězec referencí držících objekt.

Knihovna se stala standardem v komunitě Android: podle údajů GitHub projekt nasbíral přes 28 tisíc hvězdiček a je používán v aplikacích Google, Uber, Airbnb a Facebook. LeakCanary je k dispozici ve dvou hlavních verzích: klasická 1.x (s ruční konfigurací) a moderní 2.x (automatická integrace přes ContentProvider). Verze 2.x nevyžaduje úpravu třídy Application — jedna závislost stačí k plnému fungování.

Hlavním úkolem LeakCanary je detekovat situaci, kdy objekt nadále existuje v paměti poté, co jeho životní cyklus skončil. To je typické pro úniky přes statická pole, singly, neregistrovaná callbacky, anonymní třídy a uzávěry zachycující externí objekty.

Proč je LeakCanary důležitý pro vývoj Androidu

Úniky paměti na Androidu jsou kritičtější než na desktopu kvůli omezenému množství RAM na mobilních zařízeních. I únik 5–10 MB při každém přepnutí obrazovky může vést k OutOfMemoryError po 30–40 minutách používání aplikace. LeakCanary detekuje takové problémy ve fázi vývoje, aniž by čekal na pád v produkci.

Jak LeakCanary funguje?

LeakCanary používá slabé reference (WeakReference) v kombinaci s vynuceným voláním garbage collectoru. Když Activity nebo Fragment zavolá onDestroy, LeakCanary vytvoří WeakReference na tento objekt a spustí GC po krátkém zpoždění (výchozí 5 sekund). Pokud je objekt po GC stále dostupný přes WeakReference, znamená to, že je držen silnou referencí — je zaznamenán únik.

Po detekci úniku LeakCanary provede heap dump (kompletní snímek paměti aplikace ve formátu HPROF). Následně vestavěný analyzátor (Shark pro verzi 2.x) vytvoří graf dosažitelnosti od GC Roots k uniklému objektu a najde nejkratší cestu — řetězec referencí držících objekt v paměti.

kotlin
// Zjednodušená logika detekce 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() // vynucené GC
        for (ref in watchedReferences) {
            if (ref.get() != null) {
                onLeakFound(ref) // objekt přežil GC — to je únik
            }
        }
    }
}

Klíčovým momentem je vynucené volání GcTrigger.runGc(). Bez něj nelze rozlišit objekt, který skutečně unikl, od objektu, který GC ještě nestihl sesbírat. LeakCanary to dělá až třikrát: pokud je po třech GC cyklech objekt stále v paměti — únik je potvrzen.

Co je Shark — analyzátor heap dump

Shark — je vestavěný analyzátor heap dump v LeakCanary 2.x, napsaný v Kotlinu. Na rozdíl od předchozího analyzátoru HAHA, Shark nenačítá celý HPROF soubor do paměti, ale prochází jeho graf objektů s minimálními alokacemi. To snižuje spotřebu RAM během analýzy z 50 MB na 2–5 MB a zkracuje dobu analýzy z 30 sekund na 1–3 sekundy.

Jak nainstalovat a nakonfigurovat LeakCanary?

Instalace LeakCanary 2.x do moderního Android projektu zabere jeden řádek v build.gradle. Knihovna používá ContentProvider pro automatickou inicializaci — není třeba upravovat třídu Application ani přidávat kód do MainActivity. Připojení se provádí pouze pro debug-build, aby v release APK nebyl zbytečný kód.

groovy
// build.gradle (app/module)
dependencies {
    // debugImplementation — knihovna pouze pro debug-build
    debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
}

Po přidání závislosti a přestavění projektu se LeakCanary automaticky objeví v aplikaci. Při prvním spuštění knihovna zobrazí systémové oznámení o aktivaci. Všechny detekované úniky se zobrazují jako oznámení — kliknutí na oznámení otevře obrazovku s podrobnou zprávou (LeakTrace).

Pro přizpůsobení můžete vytvořit vlastní AppWatcherInstaller a přepsat parametry: časový limit čekání na GC, seznam sledovaných typů objektů, povolení ukládání heap dump na disk. Pro 90 % projektů je však výchozí konfigurace optimální.

Konfigurace pro korutiny a Jetpack Compose

Počínaje verzí 2.12 LeakCanary podporuje automatické sledování ViewModel, korutinových scopeů a State objektů Compose. Nejsou vyžadovány žádné další závislosti — knihovna sama zjistí, které Jetpack komponenty se v projektu používají, a aktivuje odpovídající detektory.

Jak číst zprávu LeakCanary

Zpráva LeakCanary (LeakTrace) — je víceřádkový řetězec referencí od GC Root k uniklému objektu. Každý řádek ukazuje třídu a pole, přes které prochází silná reference. Vývojář by měl číst řetězec zdola nahoru: spodní řádek — uniklý objekt, horní řádek — vstupní bod (GC Root).

Typický LeakTrace vypadá takto: GC Root → statické pole Application → singleton → callback → Activity. Pokud vývojář vidí takový řetězec, problém je jasný: singleton drží callback, který zachytil referenci na Activity. Řešení — nahradit silnou referenci slabou v singletonu.

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)
╰

V tomto příkladu LeakCanary ukazuje, že MainActivity je držen přes řetězec: Application → ArrayList → MainActivity → CallbackWrapper → MyCallback → zpět MainActivity. Šipka this$0 ukazuje, že anonymní třída MyCallback zachytila externí referenci na Activity. Řešení — udělat callback slabou referencí nebo jej zrušit v onDestroy.

LeakCanary také zobrazuje stav úniku pro každý prvek řetězce: NO (žádný únik — toto je kořenový prvek), YES (objekt by měl být zničen), UNKNOWN (stav se nepodařilo určit). Status UNKNOWN neznamená problém — jde o mezilehlý objekt, který LeakCanary nelze jednoznačně klasifikovat.

LeakCanary 2.x vs 1.x: klíčové rozdíly

Přechod z verze 1.x na 2.x byl radikální: vývojáři přepsali knihovnu od základů, nahradili zastaralý analyzátor HAHA vlastním motorem Shark napsaným v Kotlinu. Shark pracuje řádově rychleji, vyžaduje méně paměti pro analýzu a přesněji určuje hlavní příčiny úniků.

ParametrLeakCanary 1.xLeakCanary 2.x
Jazyk analyzátoruJava (HAHA — fork Android SDK)Kotlin (Shark — vlastní motor)
InstalaceRuční konfigurace AppWatcher v ApplicationAutomatická přes ContentProvider
Rychlost10–30 sekund na analýzu heap dump1–5 sekund na analýzu heap dump
VýkonZabírá 10–50 MB RAM při analýzeZabírá 2–10 MB RAM při analýze

Klíčovou výhodou Shark je, že nenačítá celý heap dump do paměti, ale prochází jeho referenční graf s minimálními alokacemi. To činí LeakCanary 2.x vhodným pro použití na zařízeních s nízkou RAM bez rizika OutOfMemoryError při analýze.

Ve verzi 2.x se také objevila možnost exportu heap dump do souboru pro pozdější analýzu v Android Studio Memory Profiler. K tomu je třeba povolit nastavení dumpHeapWhenLeakFound v konfiguraci AppWatcher.

Typické úniky nalezené LeakCanary

LeakCanary efektivně detekuje několik tříd úniků typických pro Android. Nejčastěji se vyskytuje únik přes statické reference na Activity — vývojáři ukládají referenci na kontext Activity v singletonu a Activity nemůže být sesbírána GC po dokončení svého životního cyklu.

Druhou nejčastější kategorií jsou úniky přes neregistrované posluchače. Pokud byl v onStart zavolán registerListener, ale v onStop/onDestroy nebyl zavolán unregisterListener — objekt-posluchač je držen systémem i po zničení aktivity. LeakCanary jednoznačně ukazuje, který posluchač a v které systémové službě zůstal aktivní.

kotlin
// Typický únik: Activity zachycena v callbacku singletonu
object AnalyticsManager {
    private var callback: ((String) -> Unit)? = null

    fun register(callback: (String) -> Unit) {
        this.callback = callback // silná reference na callback
    }

    fun unregister() {
        callback = null // NEZAPOMEŇTE zavolat v onDestroy!
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AnalyticsManager.register { event ->
            logEvent(event) // lambda zachycuje this
        }
        // pokud nezavoláte unregister v onDestroy → únik Activity
    }
}

Třetí kategorií jsou úniky přes Fragment v BackStack. Pokud je FragmentTransaction.addToBackStack() voláno bez odstranění Fragmentu při návratu, staré instance Fragmentu zůstávají v paměti. LeakCanary pomáhá odhalit takové skryté úniky v raných fázích vývoje.

Pro každý detekovaný únik LeakCanary nabízí popis a doporučení pro opravu. Ve verzi 2.14 byla přidána integrace s Android Lint — knihovna může automaticky vytvářet úkoly v issue tracker při detekci úniku v CI.

Často kladené otázky

Je třeba odstranit LeakCanary z release APK?

Ano, rozhodně. LeakCanary se připojuje přes debugImplementation v build.gradle, což jej automaticky vylučuje z release sestavení. Pokud jej připojíte přes implementation, knihovna se dostane do release APK a bude zobrazovat úniky koncovým uživatelům — to je nepřijatelné.

Zpomaluje LeakCanary chod aplikace?

Dopad na výkon je minimální. LeakCanary se aktivuje až po onDestroy komponenty a nezasahuje do vykreslování UI ani zpracování dotyků. Jediným nákladem je krátká pauza vynuceného GC (asi 100 ms) a zápis heap dump při úniku (setiny sekundy).

Jak exportovat zprávu LeakCanary?

LeakCanary automaticky ukládá heap dump ve formátu HPROF do složky aplikace. Soubor lze exportovat přes Android Studio: Device File Explorer → data/data/com.example/files/leakcanary/. Pro zobrazení otevřete soubor v Memory Profiler přes Capture → Open Heap Dump.

Funguje LeakCanary s Jetpack Compose?

Ano, od verze 2.12 LeakCanary plně podporuje Jetpack Compose. Knihovna sleduje kontexty Composition a State objekty, automaticky detekuje úniky v Composable funkcích. Samostatná konfigurace není nutná — funguje ihned.

Může se LeakCanary mýlit (false positive)?

Falešné aktivace jsou možné, ale vzácné. LeakCanary používá trojité volání GC před prohlášením úniku, což eliminuje většinu falešně pozitivních výsledků. Pokud se domníváte, že aktivace je falešná — vytvořte IgnoredReference pro konkrétní třídu v konfiguraci.

Shrnutí

  • LeakCanary — standardní knihovna pro automatickou detekci úniků paměti v Android aplikacích.
  • Knihovna používá WeakReference a vynucené GC k detekci objektů, které přežily svůj životní cyklus.
  • Heap dump je analyzován vestavěným motorem Shark, který vytváří řetězec referencí od GC Root k uniklému objektu.
  • Instalace v moderním projektu — jeden řádek v build.gradle: debugImplementation.
  • LeakCanary 2.x je kompletně přepsán v Kotlinu a pracuje 5–10krát rychleji než předchozí verze.
  • Nejčastější úniky: statické reference na Activity, neregistrovaní posluchači a Fragment v BackStack.
  • Zaveďte LeakCanary do debug-build každého projektu — předejdete tak únikům v produkci.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také