tracemalloc no Python: rastreie memória

Publicado em: 28/08/2026
Tempo de leitura: 6 minutos
A person typing on a laptop with a Python programming book visible, capturing technology and learning.

O módulo tracemalloc rastreia alocações de memória realizadas pelo Python e registra onde elas ocorreram. Ele permite medir memória atual e pico, criar snapshots, agrupar alocações por arquivo ou linha, comparar estados e aplicar filtros. É uma ferramenta importante para investigar crescimento de memória, caches sem limite, estruturas mantidas por engano e regressões entre versões de código.

tracemalloc não mede toda a memória residente do processo. Bibliotecas nativas, buffers externos, memória do sistema operacional, GPU e alocações que não passam pelos hooks rastreados podem ficar fora do resultado. Use-o em conjunto com métricas de RSS, ferramentas do sistema e conhecimento do workload.

Inicie o rastreamento

Chame start() antes do trecho que deseja observar.

import tracemalloc

tracemalloc.start()
executar_aplicacao()

Começar cedo captura imports e inicialização; começar tarde reduz ruído e overhead.

Número de frames

start(nframe) define quantos frames de traceback guardar por alocação.

tracemalloc.start(10)

Mais frames ajudam a entender a origem completa, mas aumentam consumo e custo.

Verifique se está ativo

is_tracing() informa se o rastreamento está habilitado.

if not tracemalloc.is_tracing():
    tracemalloc.start(5)

Uma biblioteca não deve iniciar ou parar tracing global sem documentar o impacto sobre a aplicação.

Memória atual e pico

get_traced_memory() retorna bytes atuais e pico rastreados.

atual, pico = tracemalloc.get_traced_memory()
print(atual, pico)

O pico é útil para detectar uma operação temporariamente cara mesmo quando a memória é liberada depois.

Resete o pico

reset_peak() redefine o valor máximo sem apagar alocações atuais.

tracemalloc.reset_peak()
executar_etapa()
atual, pico_etapa = tracemalloc.get_traced_memory()

Isso permite medir picos por fase.

Crie um snapshot

take_snapshot() captura as alocações rastreadas naquele instante.

snapshot = tracemalloc.take_snapshot()

Snapshots podem consumir memória. Não crie continuamente em produção sem controle.

Estatísticas por linha

statistics("lineno") agrupa alocações por linha.

for estatistica in snapshot.statistics("lineno")[:10]:
    print(estatistica)

Observe tamanho total, contagem e média. Uma linha com muitas pequenas alocações pode ser tão importante quanto uma alocação grande.

Por arquivo ou traceback

Use filename para agrupar por arquivo e traceback para distinguir caminhos de chamada.

top = snapshot.statistics("traceback")[:5]
for item in top:
    print(item.size, item.count)
    for frame in item.traceback.format():
        print(frame)

Tracebacks são mais detalhados e podem gerar muitos grupos.

Compare snapshots

Uma comparação mostra crescimento e redução entre dois momentos.

antes = tracemalloc.take_snapshot()
executar_cenario()
depois = tracemalloc.take_snapshot()

for diferenca in depois.compare_to(antes, "lineno")[:10]:
    print(diferenca)

Repita o cenário várias vezes para separar aquecimento de crescimento contínuo.

Baseline após aquecimento

Imports, caches de bytecode, pools e inicialização criam alocações legítimas.

Execute uma fase de warm-up, force o estado esperado e só então capture o snapshot de referência.

Detecte crescimento por repetição

for _ in range(5):
    executar_cenario()
    gc.collect()
    snapshot = tracemalloc.take_snapshot()
    registrar(snapshot)

O uso de gc.collect() em diagnóstico pode reduzir ruído, mas não representa necessariamente o comportamento normal de produção.

Filtros

Filter e DomainFilter incluem ou excluem traces.

filtros = [
    tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
    tracemalloc.Filter(False, "*/site-packages/*"),
]
filtrado = snapshot.filter_traces(filtros)

Não filtre cedo demais. Uma dependência externa pode ser a origem real do crescimento.

Filtros inclusivos e exclusivos

Um filtro exclusivo remove correspondências; um inclusivo mantém apenas correspondências compatíveis.

Documente os padrões usados para que relatórios possam ser reproduzidos.

Traceback de uma alocação

APIs de trace permitem inspecionar os frames registrados para blocos individuais.

Na prática, estatísticas agregadas costumam ser mais úteis do que listar milhões de traces.

Salve e carregue snapshots

Snapshots podem ser persistidos para análise posterior.

snapshot.dump("memoria.snap")
carregado = tracemalloc.Snapshot.load("memoria.snap")

O arquivo pode revelar paths e nomes internos. Proteja-o como artefato de diagnóstico.

Use linecache no relatório

O código-fonte das linhas pode ser recuperado para melhorar a saída.

import linecache

frame = estatistica.traceback[0]
linha = linecache.getline(frame.filename, frame.lineno).strip()

Consulte linecache no Python.

Inicie antes do import

Para rastrear alocações de startup, use opções do interpretador ou variável de ambiente suportada pela versão do Python.

Esse modo ajuda quando o crescimento acontece durante imports, mas produz mais ruído.

Overhead

Guardar traces para cada alocação consome CPU e memória. O custo cresce com o número de frames.

Em produção, use por janela curta, amostragem operacional controlada ou instância de diagnóstico.

Memória rastreada versus RSS

RSS pode continuar alto mesmo após objetos Python serem liberados, porque allocators mantêm arenas para reutilização e o sistema gerencia páginas.

Uma queda no valor rastreado sem queda no RSS não prova vazamento. Analise tendências e arquitetura do allocator.

Memória nativa

NumPy, bibliotecas de imagem, compressão, drivers e extensões C podem alocar fora do domínio visível.

Se RSS cresce mas tracemalloc permanece estável, use ferramentas nativas e métricas específicas da biblioteca.

Objetos vivos e referências

tracemalloc mostra onde memória foi alocada, não necessariamente por que o objeto continua vivo.

Combine com gc, inspeção de referências e análise de caches para descobrir ownership.

Leaks versus caches

Um cache pode crescer por design, mas sem limite se torna um vazamento operacional.

Verifique tamanho máximo, expiração, cardinalidade de chaves e política de remoção.

Threads

O rastreamento é global ao processo. Alocações de várias threads aparecem nos snapshots.

Inclua contexto de workload e sincronize o cenário de teste para comparar fases equivalentes.

Processos

Cada processo possui seu próprio estado de tracemalloc.

Em multiprocessing, colete snapshots ou métricas em cada worker e agregue fora do processo. Não confunda memória individual com total do serviço.

Testes de regressão

Um teste pode executar um cenário repetido e verificar que o crescimento líquido permanece abaixo de uma margem.

Evite limites rígidos demais: versão do Python, plataforma e imports alteram números. Compare tendências e use tolerância.

Measure uma função

def medir(funcao, *args, **kwargs):
    tracemalloc.start(10)
    try:
        tracemalloc.reset_peak()
        resultado = funcao(*args, **kwargs)
        atual, pico = tracemalloc.get_traced_memory()
        return resultado, atual, pico
    finally:
        tracemalloc.stop()

Não pare um tracing iniciado por outro componente. Coordene ownership.

clear_traces

clear_traces() remove traces registrados sem necessariamente alterar objetos vivos.

Use para iniciar uma fase limpa de diagnóstico, entendendo que você perde o histórico anterior.

stop

stop() desativa o rastreamento e limpa traces conforme a semântica da versão.

Após parar, snapshots anteriores ainda podem ser analisados como objetos independentes.

Relatórios úteis

Inclua arquivo, linha, código, tamanho, diferença, contagem e média. Mostre unidades legíveis, mas preserve bytes para cálculos.

Não despeje milhares de linhas; destaque os maiores crescimentos e permita drill-down.

Segurança e privacidade

Paths e linhas de código podem revelar nomes de clientes, diretórios internos e lógica proprietária.

Redija informações antes de anexar snapshots ou relatórios a tickets públicos.

Observabilidade

tracemalloc é melhor para diagnóstico do que como métrica contínua de alta frequência.

Use RSS, heap do processo, contagem de objetos e métricas de cache para monitoramento; ative snapshots quando a tendência indicar problema.

Testes

Teste um cenário estável, um crescimento intencional, liberação de objetos, cache limitado, múltiplas threads e workers separados.

Controle warm-up, force entradas determinísticas e repita para reduzir ruído.

Erros comuns

Os erros mais frequentes são confundir memória rastreada com RSS, capturar baseline antes do warm-up, usar apenas um snapshot, filtrar dependências cedo, ignorar alocações nativas, guardar frames demais em produção e concluir que todo crescimento é vazamento.

Conclusão

tracemalloc mostra onde o Python aloca memória e como o perfil muda ao longo do tempo. Use snapshots comparáveis, filtros documentados, picos por fase e cenários repetidos.

Combine resultados com RSS, garbage collector e métricas de bibliotecas nativas. Consulte a documentação oficial de tracemalloc, linecache no Python e o artigo sobre vazamentos de memória.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    queue no Python: comunique threads

    Aprenda queue no Python para comunicar threads com FIFO, LIFO, prioridade, backpressure, task_done, join, sentinelas e shutdown seguro.

    Ler mais

    Tempo de leitura: 6 minutos
    28/08/2026
    Flat lay of a complete toolset neatly organized in a workshop setting, essential for auto repair tasks.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    selectors no Python: vários sockets

    Aprenda selectors no Python para multiplexar sockets, controlar leitura e escrita parcial, buffers, timeouts, wakeup e backpressure.

    Ler mais

    Tempo de leitura: 6 minutos
    28/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextvars no Python: contexto assíncrono

    Aprenda contextvars no Python para contexto por task, request IDs, logging, copy_context, propagação a threads e restauração segura com tokens.

    Ler mais

    Tempo de leitura: 6 minutos
    28/08/2026
    Person writing appointments on a calendar with a blue pen. High angle view.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sched no Python: agende eventos

    Aprenda sched no Python para agendar eventos, usar prioridades, cancelar tarefas, criar recorrência sem drift e integrar executores.

    Ler mais

    Tempo de leitura: 6 minutos
    28/08/2026
    Close-up of a vibrant yellow python coiled with textured scales in vibrant light.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    bisect no Python: listas ordenadas

    Aprenda bisect no Python para busca binária, inserção ordenada, duplicatas, funções key, faixas, rankings e sincronização segura.

    Ler mais

    Tempo de leitura: 5 minutos
    28/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    heapq no Python: filas de prioridade

    Aprenda heapq no Python para filas de prioridade, top-k, merge, empates, atualização de prioridades, lazy deletion e backpressure.

    Ler mais

    Tempo de leitura: 5 minutos
    28/08/2026