Heap Dump: o que é, análise do heap e eliminação de vazamentos de memória

Autor: IT Sectr Publicado: 2026-05-07 Tempo de leitura: 10 min

Heap Dump (dump do heap) é uma captura da memória dinâmica do aplicativo contendo informações completas sobre todos os objetos vivos: suas classes, tamanhos, referências mútuas e acessibilidade a partir das raízes GC. Heap Dump é a principal ferramenta para analisar vazamentos de memória e otimizar o consumo de recursos. De acordo com Android Developers, a análise de heap dumps permite detectar até 95% dos vazamentos de memória, incluindo referências cíclicas, listeners esquecidos e referências estáticas não liberadas.

Pontos Principais

  • Heap Dump é uma captura de toda a memória dinâmica do aplicativo com informações sobre cada objeto e as referências entre eles.
  • Android Studio Memory Profiler permite capturar heap dumps em tempo real para aplicativos Java e Kotlin.
  • Xcode Instruments fornece a ferramenta Allocations para criar e analisar heap dumps no iOS/macOS.
  • Shallow e retained size são métricas-chave: shallow é o tamanho do próprio objeto, retained é o tamanho do objeto mais todos os objetos que ele retém.
  • A análise do heap dump inclui a busca no dominator tree, maiores retained objects e caminhos mais curtos para as raízes GC.

O que é um heap dump e para que serve

Heap dump é um despejo completo do heap da máquina virtual — a área de memória onde residem todos os objetos criados dinamicamente. Em Java e Kotlin é o heap Dalvik/ART no Android, em Swift e Objective-C é o heap gerenciado por ARC no iOS. Um heap dump captura cada objeto, sua classe, tamanho, campos, referências a outros objetos e flags de acessibilidade a partir das raízes GC (variáveis de pilha, campos estáticos, referências JNI).

O principal objetivo de um heap dump é a detecção de vazamentos de memória. Um vazamento ocorre quando um aplicativo continua mantendo referências a objetos que não são mais necessários, impedindo sua coleta pelo garbage collector (ou liberação via ARC). Causas típicas: listeners de eventos não cancelados ao destruir uma activity; singletons com referências ao contexto; closures que capturam self; coleções estáticas onde dados são adicionados sem remoção. Um heap dump fornece uma imagem precisa: quais objetos estão “vivos”, quais são desnecessários e quem exatamente está referenciando-os.

De acordo com Google I/O, mais de 60% dos relatórios de crash de aplicativos Android estão relacionados a OutOfMemoryError, e em 80% dos casos a causa raiz é um vazamento de memória detectável via heap dump. Para aplicativos iOS a situação é similar: vazamentos devido a retain cycles são uma das causas mais comuns de crashes, identificados através do instrumento Allocations no Xcode.

Quando um heap dump é necessário

Um heap dump deve ser realizado quando os seguintes sintomas aparecem: o aplicativo consome memória linearmente durante ações repetitivas (navegar para frente e para trás entre telas); após fechar uma tela, a memória não retorna ao nível inicial; ocorrem OutOfMemoryError ou avisos de memória no iOS; o aplicativo termina por exceder o limite de memória (EXC_RESOURCE_RESOURCE no iOS). A coleta regular de heap dumps faz parte do protocolo de cultura de engenharia em grandes projetos móveis como Instagram e Spotify.

Heap dump no Android Studio: obtenção e análise

Android Studio fornece o Memory Profiler — uma ferramenta integrada para capturar heap dumps em tempo real. Acessível através de View → Tool Windows → Profiler. Após iniciar o aplicativo, selecione a sessão, vá para a aba Memory e clique em Dump Java Heap. O Android Studio pausa o aplicativo, realiza um dump do heap ART e carrega o resultado para análise. O arquivo de dump está no formato .hprof — o padrão HPROF compatível com a maioria dos analisadores de memória.

Após carregar o dump, o Android Studio exibe uma tabela de objetos com colunas: Allocations (quantidade de instâncias), Native Size (memória fora do heap ART), Shallow Size (memória do próprio objeto), Retained Size (memória do objeto incluindo todo seu subgrafo). A filtragem por nome de classe, ordenação por retained size e pesquisa por pacotes permitem encontrar rapidamente as áreas problemáticas.

kotlin
// Vazamento típico — um listener não cancelado no onDestroy
class MainActivity : AppCompatActivity() {
    private val sensorManager by lazy {
        getSystemService(SENSOR_SERVICE) as SensorManager
    }
    private val listener = MySensorListener()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sensorManager.registerListener(listener,
            sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
            SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onDestroy() {
        super.onDestroy()
        // ❌ Faltando sensorManager.unregisterListener(listener)
        // → Activity não será coletada pelo GC, heap dump mostrará o vazamento
    }
}

Análise do dominator tree no Android Studio

A aba Dominator Tree mostra os objetos que retêm a maior quantidade de memória. Se um objeto for removido do dominator tree, toda a memória que ele retém fica disponível para coleta. Esta é uma ferramenta-chave: em vez de examinar milhares de objetos, você foca em 10–20 que controlam 80–90% da memória. De acordo com Google, a análise do dominator tree é a forma mais eficaz de encontrar um ponto de vazamento, reduzindo o tempo de análise de horas para minutos.

Heap dump no Xcode Instruments: Allocations e Leaks

Xcode Instruments fornece duas ferramentas para trabalhar com heap dumps: Allocations — captura de dumps de heap com gráfico de consumo em tempo real; Leaks — busca automática de vazamentos através da análise de retain cycles. Allocations exibe todos os objetos no heap, seu tamanho, número de criações (allocations) e liberações (deallocations). A diferença entre o número de criações e liberações para uma classe específica indica um potencial vazamento.

A captura de um heap dump no Allocations é feita com o botão Snapshot Memory — a ferramenta pausa o aplicativo e faz um dump completo. Depois disso, as visualizações padrão estão disponíveis: lista de objetos por classe, árvore de chamadas (call tree) para cada objeto e um gerador de relatórios. Ao contrário do Android Studio, o Xcode não usa .hprof, mas armazena dados em seu próprio formato .trace compatível com Instruments.

swift
// Vazamento típico de iOS — retain cycle através de um closure
class NetworkManager {
    var onComplete: ((Data) -> Void)?

    func startRequest() {
        // ❌ Closure captura self — retain cycle
        onComplete = { data in
            self.process(data)
        }
    }
    func process(_ data: Data) {}
}

O instrumento Leaks detecta automaticamente retain cycles e vazamentos através da análise do grafo de referências. Ele marca objetos com vazamento com um ícone roxo e mostra o caminho para a raiz (GC root). Para eliminar um retain cycle, basta adicionar [weak self] ou [unowned self] na captura do closure. A execução regular do instrumento Leaks é uma etapa obrigatória no pipeline de CI em equipes que usam Swift para desenvolvimento iOS.

swift
// Correção — referência fraca para self
onComplete = { [weak self] data in
    guard let self else { return }
    self.process(data)
}

Shallow size, retained size e dominator tree

Para uma análise correta de um heap dump é necessário compreender três métricas-chave. Shallow size é o volume de memória ocupado diretamente pelo objeto: seus campos, cabeçalho (header) e alinhamento. Para um objeto Java/Kotlin típico, o shallow size é de 16–40 bytes. Retained size é o shallow size do objeto mais a soma do shallow size de todos os objetos que são acessíveis apenas através deste objeto (ou seja, se tornariam lixo se ele fosse removido). O retained size mostra o impacto real do objeto no consumo de memória.

MétricaDescriçãoExemplo
Shallow sizeTamanho do próprio objeto em bytesBitmap (100×100) = 40.016 B
Retained sizeShallow size + tudo que ele retémActivity com View Tree = 2–5 MB
Deep sizeRetained size + objetos aninhados de outros grafosScrollView com adaptador = 10–50 MB

Dominator tree é uma estrutura onde cada objeto referencia seu “dominador” — o objeto que controla sua acessibilidade. Se o dominador for removido, todos os objetos de sua subárvore se tornam lixo. A análise do dominator tree é a forma mais rápida de descobrir qual objeto retém mais memória. De acordo com Eclipse MAT (Memory Analyzer Tool), 90% dos vazamentos são detectados revisando o top-20 do dominator tree em 5 minutos.

Análise de vazamentos de memória via heap dump

O processo de análise de um vazamento via heap dump consiste em várias etapas. Etapa 1: realize a ação que deve liberar memória (feche a tela, finalize a operação). Etapa 2: chame o GC (System.gc() no Android, snapshot forçado no Xcode) e faça um heap dump. Etapa 3: encontre os objetos que deveriam ter sido destruídos (por exemplo, uma instância de Activity após finish). Etapa 4: para o objeto suspeito, execute Path to GC Roots — a cadeia de referências que mantém o objeto vivo. A última referência na cadeia é a causa do vazamento.

Path to GC Roots

A função Path to GC Roots está disponível no Android Studio Profiler, Eclipse MAT e Xcode Instruments. Ela mostra a cadeia mais curta de referências de uma raiz GC até o objeto problemático. Excluindo referências fracas (weak) e suaves (soft), você obtém apenas as fortes (strong) — aquelas que realmente impedem a coleta. De acordo com Square Engineering, 70% dos vazamentos em aplicativos Android são causados por apenas dois padrões: referências estáticas para Activity ou Context e listeners registrados mas não cancelados.

kotlin
// Exemplo de vazamento através de referência estática
object AppCache {
    private val cache = mutableMapOf<String, Any>()

    fun storeActivityReference(activity: Activity) {
        cache["current_activity"] = activity // ❌ Vazamento!
    }
}

// Correção: referência fraca
object AppCacheFixed {
    private val cache = mutableMapOf<String, WeakReference<Any>>()
}

Comparação de dois heap dumps

A técnica de modo de comparação é um dos métodos mais eficazes para encontrar vazamentos. Faça um heap dump antes e depois de uma ação repetitiva (por exemplo, cinco navegações para uma tela e volta). Compare o número de instâncias das classes-chave: se o número de Activity aumentou embora todas as atividades tenham sido fechadas — é um vazamento. Android Studio e Eclipse MAT suportam comparação automática de dumps com destaque de diferenças. De acordo com Google, a comparação de dumps permite encontrar vazamentos invisíveis em uma análise única devido ao efeito de acúmulo.

Recomendações práticas para reduzir o consumo de memória

Com base na análise de heap dumps em projetos reais, práticas comprovadas de otimização de memória foram desenvolvidas. Use WeakReference para caches, callbacks e referências ao contexto em objetos de longa duração. Cancele os listeners em onPause/onDestroy para Android e deinit para iOS. Evite grandes coleções estáticas — se necessárias, use LruCache com limite de tamanho. Otimize os Bitmaps: carregue imagens com o inSampleSize correto, use Glide ou Picasso com cache de disco.

Perfilamento de memória durante o desenvolvimento

Inclua a captura regular de heap dumps em seu pipeline de CI. Configure uma tarefa que execute testes de UI instrumentados, realize os cenários de usuário principais e compare o heap dump com a linha de base. Se o retained size crescer mais de 5% em relação à linha de base, o build é marcado como regressão. Esta abordagem é praticada no Airbnb, Uber e outras empresas com altos requisitos de qualidade. De acordo com Uber Engineering, a implementação da análise automática de heap dumps no CI reduziu os erros relacionados à memória em 70% em um trimestre.

groovy
// Exemplo de tarefa Gradle para heap dump automático no CI
task profileMemory(type: Exec) {
    commandLine 'adb', 'shell',
        'am start -n com.example/.MainActivity'
    // Aguardando carregamento
    doLast {
        exec { commandLine 'adb', 'shell',
            'am broadcast -a com.example.DUMP_HEAP' }
    }
}

Perguntas Frequentes

Qual a diferença entre shallow size e retained size?

Shallow size é o tamanho do próprio objeto (campos + cabeçalho). Retained size é o tamanho do objeto mais todos os objetos que se tornariam lixo se ele fosse removido. O retained size é o principal indicador do impacto de um objeto no consumo de memória.

Como fazer um heap dump em um dispositivo Android físico?

Através do Android Studio Profiler, selecione o dispositivo e processo, clique em Dump Java Heap. Alternativamente, via linha de comando: adb shell am dumpheap PID /sdcard/dump.hprof, depois adb pull.

Por que um heap dump pode ser enorme (500 MB+)?

Um heap dump inclui todos os objetos vivos. Se o aplicativo usa caches, Bitmaps ou processa grandes dados, o dump pode atingir centenas de megabytes. Filtre por classes ou use Eclipse MAT para carregar apenas o índice.

Pode-se analisar um heap dump sem Android Studio?

Sim, use Eclipse MAT (Memory Analyzer Tool) — uma ferramenta gratuita para analisar arquivos .hprof. Suporta dominator tree, path to GC roots, comparação de dumps e detecção automática de vazamentos via Leak Suspects Report.

Um heap dump reduz o desempenho do aplicativo?

O dump em si — sim, porque a coleta do dump pausa todas as threads (stop-the-world). Sem dump — não. Faça dumps em ambientes controlados (bancada de teste, CI), não em produção.

Resumo

  • Heap Dump é uma captura completa do heap do aplicativo com informações sobre cada objeto e as relações entre eles.
  • Android Studio Memory Profiler e Xcode Instruments Allocations são as principais ferramentas de captura de dumps.
  • Shallow size é o tamanho do próprio objeto; retained size é o tamanho do objeto com todo seu subgrafo de dependências.
  • Dominator tree mostra os objetos que controlam a maior quantidade de memória.
  • Path to GC Roots é a cadeia de referências fortes que impede um objeto de ser coletado.
  • A comparação de dois heap dumps (antes/depois de uma ação) é o método mais confiável para detectar vazamentos.
  • A automação da captura e análise de heap dumps no CI previne regressões de memória durante o desenvolvimento.

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