LeakCanary — o que é, biblioteca para encontrar vazamentos no Android

Autor: IT Sectr Publicado: 2026-03-30 Tempo de leitura: 9 min

LeakCanary é uma biblioteca de código aberto da Square para detecção automática de vazamentos de memória em aplicativos Android. Ela se integra ao processo de desenvolvimento e monitora em tempo real o ciclo de vida de Activity, Fragment, ViewModel e outros componentes, sinalizando vazamentos assim que ocorrem. De acordo com o Square Open Source, a biblioteca é usada em milhares de projetos e é considerada o padrão de fato para diagnóstico de memória no Android.

Principais pontos

  • LeakCanary é uma biblioteca para detecção automática de vazamentos de memória no Android.
  • Mecanismo de funcionamento baseado em WeakReference e ativação manual do GC após a destruição do componente.
  • Heap dump é criado automaticamente ao detectar um vazamento e analisado pelo analisador integrado.
  • Resultado — uma cadeia de referências exata (leak trace) que aponta para a localização do vazamento no código.
  • LeakCanary 2.x não requer configuração manual — basta uma dependência no build.gradle.

O que é LeakCanary?

LeakCanary é uma biblioteca para detecção automática de vazamentos de memória em aplicativos Android, desenvolvida pela Square. Ela se integra ao processo de compilação do aplicativo e monitora automaticamente se objetos que deveriam ser destruídos (Activity, Fragment, View) permanecem na memória. Ao detectar um vazamento, o LeakCanary gera um heap dump e analisa a cadeia de referências que retém o objeto.

A biblioteca se tornou um padrão na comunidade Android: de acordo com o GitHub, o projeto tem mais de 28 mil estrelas e é usado em aplicativos do Google, Uber, Airbnb e Facebook. O LeakCanary está disponível em duas versões principais: a clássica 1.x (com configuração manual) e a moderna 2.x (integração automática via ContentProvider). A versão 2.x não requer modificação da classe Application — a dependência é suficiente para o funcionamento completo.

A principal tarefa do LeakCanary é detectar quando um objeto continua existindo na memória após seu ciclo de vida ter terminado. Isso é típico de vazamentos através de campos estáticos, singletons, callbacks não registrados, classes anônimas e closures que capturam objetos externos.

Por que o LeakCanary é importante para o desenvolvimento Android

Os vazamentos de memória no Android são mais críticos do que no desktop devido à RAM limitada em dispositivos móveis. Mesmo um vazamento de 5–10 MB em cada transição de tela pode levar a um OutOfMemoryError após 30–40 minutos de uso do aplicativo. O LeakCanary detecta esses problemas na fase de desenvolvimento, sem esperar por uma falha em produção.

Como o LeakCanary funciona?

LeakCanary usa referências fracas (WeakReference) combinadas com coleta de lixo forçada. Quando uma Activity ou Fragment chama onDestroy, o LeakCanary cria uma WeakReference para esse objeto e executa o GC após um breve atraso (5 segundos por padrão). Se o objeto ainda estiver acessível via WeakReference após o GC, ele está sendo retido por uma referência forte — um vazamento é registrado.

Após detectar um vazamento, o LeakCanary faz um heap dump (despejo de memória) — um instantâneo completo da memória do aplicativo no formato HPROF. Em seguida, o analisador integrado (Shark para a versão 2.x) constrói um grafo de acessibilidade das GC Roots até o objeto vazado e encontra o caminho mais curto — a cadeia de referências que mantém o objeto na memória.

kotlin
// Lógica simplificada de detecção do 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() // GC forçado
        for (ref in watchedReferences) {
            if (ref.get() != null) {
                onLeakFound(ref) // objeto sobreviveu ao GC — é um vazamento
            }
        }
    }
}

O ponto chave é a chamada forçada a GcTrigger.runGc(). Sem ela, é impossível distinguir um objeto que realmente vazou de um que o GC ainda não coletou. O LeakCanary faz isso até três vezes: se após três ciclos de GC o objeto ainda estiver na memória, o vazamento é confirmado.

O que é Shark — o analisador de heap dump

Shark é o analisador de heap dump integrado ao LeakCanary 2.x, escrito em Kotlin. Ao contrário do analisador anterior HAHA, o Shark não carrega todo o arquivo HPROF na memória, mas percorre seu grafo de objetos com alocações mínimas. Isso reduz o consumo de RAM durante a análise de 50 MB para 2–5 MB e encurta o tempo de análise de 30 segundos para 1–3 segundos.

Como instalar e configurar o LeakCanary?

Instalar o LeakCanary 2.x em um projeto Android moderno leva uma linha no build.gradle. A biblioteca usa ContentProvider para inicialização automática — não é necessário modificar a classe Application ou adicionar código ao MainActivity. A dependência é adicionada apenas para builds debug, para que os APKs de lançamento não contenham código extra.

groovy
// build.gradle (app/module)
dependencies {
    // debugImplementation — biblioteca apenas para builds debug
    debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
}

Após adicionar a dependência e reconstruir o projeto, o LeakCanary aparece automaticamente no aplicativo. Na primeira inicialização, a biblioteca mostra uma notificação do sistema confirmando a ativação. Todos os vazamentos detectados aparecem como notificações — tocar em uma notificação abre uma tela com um relatório detalhado (LeakTrace).

Para personalização, você pode criar seu próprio AppWatcherInstaller e sobrescrever parâmetros: tempo limite do GC, lista de tipos de objetos rastreados, ativação do salvamento de heap dump em disco. No entanto, para 90% dos projetos, a configuração padrão é ideal.

Configuração para corrotinas e Jetpack Compose

A partir da versão 2.12, o LeakCanary suporta rastreamento automático de ViewModel, escopos de corrotinas e objetos State do Compose. Nenhuma dependência adicional é necessária — a biblioteca detecta automaticamente quais componentes do Jetpack estão sendo usados no projeto e ativa os detectores correspondentes.

Como ler um relatório do LeakCanary

Um relatório do LeakCanary (LeakTrace) é uma cadeia de referências de várias linhas da GC Root até o objeto vazado. Cada linha mostra a classe e o campo através dos quais uma referência forte passa. O desenvolvedor deve ler a cadeia de baixo para cima: a linha inferior é o objeto vazado, a linha superior é o ponto de entrada (GC Root).

Um LeakTrace típico se parece com: GC Root → campo estático da Application → singleton → callback → Activity. Se um desenvolvedor vê essa cadeia, o problema está claro: o singleton mantém um callback que capturou uma referência à Activity. A solução é substituir a referência forte por uma fraca no 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)
╰

Neste exemplo, o LeakCanary mostra que a MainActivity é retida através da cadeia: Application → ArrayList → MainActivity → CallbackWrapper → MyCallback → MainActivity novamente. A seta this$0 indica que a classe anônima MyCallback capturou uma referência externa à Activity. A solução é tornar o callback uma referência fraca ou cancelá-lo no onDestroy.

O LeakCanary também mostra o status do vazamento para cada elemento da cadeia: NO (sem vazamento — é um elemento raiz), YES (objeto deve ser destruído), UNKNOWN (não foi possível determinar o status). O status UNKNOWN não significa um problema — é um objeto intermediário que o LeakCanary não pode classificar de forma conclusiva.

LeakCanary 2.x vs 1.x: diferenças principais

A transição da versão 1.x para a 2.x foi radical: os desenvolvedores reescreveram a biblioteca do zero, substituindo o antigo analisador HAHA pelo próprio motor Shark, escrito em Kotlin. O Shark é uma ordem de grandeza mais rápido, requer menos memória para análise e determina com mais precisão as causas raiz dos vazamentos.

ParâmetroLeakCanary 1.xLeakCanary 2.x
Linguagem do analisadorJava (HAHA — fork do Android SDK)Kotlin (Shark — motor próprio)
InstalaçãoConfiguração manual do AppWatcher na ApplicationAutomática via ContentProvider
Velocidade10–30 segundos para análise de heap dump1–5 segundos para análise de heap dump
DesempenhoOcupa 10–50 MB de RAM durante a análiseOcupa 2–10 MB de RAM durante a análise

A principal vantagem do Shark é que ele não carrega todo o heap dump na memória, mas percorre seu grafo de referências com alocações mínimas. Isso torna o LeakCanary 2.x adequado para uso em dispositivos com pouca RAM sem risco de OutOfMemoryError durante a análise.

A versão 2.x também introduziu a capacidade de exportar heap dumps para um arquivo para análise posterior no Android Studio Memory Profiler. Para isso, ative a configuração dumpHeapWhenLeakFound na configuração do AppWatcher.

Vazamentos típicos encontrados pelo LeakCanary

LeakCanary detecta eficazmente várias classes de vazamentos comuns no Android. O mais frequente é o vazamento através de referências estáticas a uma Activity — desenvolvedores mantêm uma referência ao contexto da Activity em um singleton, e a Activity não pode ser coletada pelo GC após o término de seu ciclo de vida.

A segunda categoria mais comum são vazamentos através de ouvintes não registrados. Se registerListener foi chamado no onStart mas unregisterListener não foi chamado no onStop/onDestroy, o objeto ouvinte é retido pelo sistema mesmo após a atividade ser destruída. O LeakCanary mostra claramente qual ouvinte e em qual serviço do sistema permanece vivo.

kotlin
// Vazamento típico: Activity capturada em um callback de singleton
object AnalyticsManager {
    private var callback: ((String) -> Unit)? = null

    fun register(callback: (String) -> Unit) {
        this.callback = callback // referência forte ao callback
    }

    fun unregister() {
        callback = null // NÃO ESQUEÇA de chamar no onDestroy!
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AnalyticsManager.register { event ->
            logEvent(event) // lambda captura this
        }
        // se unregister não for chamado no onDestroy → vazamento de Activity
    }
}

A terceira categoria são vazamentos através de Fragment na BackStack. Se FragmentTransaction.addToBackStack() é chamado sem remover o Fragment ao voltar, instâncias antigas do Fragment permanecem na memória. O LeakCanary ajuda a detectar esses vazamentos ocultos nos estágios iniciais do desenvolvimento.

Para cada vazamento detectado, o LeakCanary fornece uma descrição e recomendações para correção. A versão 2.14 adicionou integração com o Android Lint — a biblioteca pode criar automaticamente tarefas no rastreador de problemas quando um vazamento é detectado no CI.

Perguntas frequentes

É necessário remover o LeakCanary do APK de lançamento?

Sim, absolutamente. O LeakCanary é adicionado via debugImplementation no build.gradle, o que o exclui automaticamente dos builds de lançamento. Se usar implementation, a biblioteca será incluída no APK de lançamento e mostrará vazamentos aos usuários finais — isso é inaceitável.

O LeakCanary diminui a velocidade do aplicativo?

O impacto no desempenho é mínimo. O LeakCanary só é ativado após o onDestroy do componente e não interfere na renderização da UI ou no processamento de toques. O único custo é uma breve pausa forçada do GC (cerca de 100 ms) e a gravação do heap dump quando ocorre um vazamento (frações de segundo).

Como exportar um relatório do LeakCanary?

O LeakCanary salva automaticamente os heap dumps no formato HPROF na pasta do aplicativo. O arquivo pode ser exportado via Android Studio: Device File Explorer → data/data/com.example/files/leakcanary/. Para visualizá-lo, abra o arquivo no Memory Profiler através de Capture → Open Heap Dump.

O LeakCanary funciona com Jetpack Compose?

Sim, a partir da versão 2.12 o LeakCanary é totalmente compatível com Jetpack Compose. A biblioteca rastreia contextos de Composition e objetos State, detectando automaticamente vazamentos em funções Composable. Nenhuma configuração separada é necessária — funciona imediatamente.

O LeakCanary pode produzir falsos positivos?

Falsos positivos são possíveis, mas raros. O LeakCanary usa uma chamada tripla ao GC antes de declarar um vazamento, o que elimina a maioria dos falsos positivos. Se você acredita que uma detecção é um falso positivo, crie um IgnoredReference para a classe específica na configuração.

Resumo

  • LeakCanary é a biblioteca padrão para detecção automática de vazamentos de memória em aplicativos Android.
  • A biblioteca usa WeakReference e GC forçado para detectar objetos que sobrevivem ao seu ciclo de vida.
  • Heap dump analisado pelo motor Shark integrado, que constrói uma cadeia de referências da GC Root ao objeto vazado.
  • Instalação em um projeto moderno: uma linha no build.gradle: debugImplementation.
  • LeakCanary 2.x foi completamente reescrito em Kotlin e roda 5–10 vezes mais rápido que a versão anterior.
  • Vazamentos mais comuns: referências estáticas a Activity, ouvintes não registrados e Fragment na BackStack.
  • Adicione o LeakCanary ao build debug de cada projeto — ele previne vazamentos em produção.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também