tracemalloc en Python: rastrea memoria

Publicado el: 28/08/2026
Tempo de leitura: 6 minutos
Close-up view of a computer screen displaying code in a software development environment.

El módulo tracemalloc rastrea asignaciones de memoria realizadas por Python y registra dónde ocurrieron. Permite medir memoria actual y pico, crear snapshots, agrupar asignaciones por archivo o línea, comparar estados y aplicar filtros. Es una herramienta importante para investigar crecimiento de memoria, caches sin límite, estructuras retenidas por error y regresiones entre versiones.

tracemalloc no mide toda la memoria residente del proceso. Bibliotecas nativas, buffers externos, memoria del sistema operativo, GPU y asignaciones que no pasan por los allocators rastreados pueden quedar fuera. Combínalo con métricas RSS, herramientas del sistema y conocimiento del workload.

Inicia el rastreo

Llama start() antes del código que quieres observar.

import tracemalloc

tracemalloc.start()
ejecutar_aplicacion()

Iniciar temprano captura imports e inicialización; iniciar más tarde reduce ruido y overhead.

Profundidad de frames

start(nframe) define cuántos frames de traceback se guardan por asignación.

tracemalloc.start(10)

Más frames mejoran la atribución, pero aumentan consumo y coste.

Comprueba si está activo

is_tracing() informa el estado global.

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

Una biblioteca no debería iniciar o detener el tracing global sin documentar su impacto.

Memoria actual y pico

get_traced_memory() devuelve bytes actuales y pico rastreados.

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

El pico revela una operación temporalmente costosa aunque la memoria sea liberada después.

Resetea el pico

reset_peak() redefine el máximo sin borrar las asignaciones actuales.

tracemalloc.reset_peak()
ejecutar_etapa()
actual, pico_etapa = tracemalloc.get_traced_memory()

Esto permite medir picos por fase.

Crea un snapshot

take_snapshot() captura las asignaciones rastreadas en un instante.

snapshot = tracemalloc.take_snapshot()

Los snapshots consumen memoria. No los crees continuamente en producción sin límites.

Estadísticas por línea

statistics("lineno") agrupa asignaciones por línea.

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

Observa tamaño total, cantidad y media. Muchas asignaciones pequeñas pueden ser tan importantes como una grande.

Agrupa por archivo o traceback

Usa filename para archivo y traceback para diferenciar caminos de llamada.

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

El agrupamiento por traceback es detallado y puede generar muchos grupos.

Compara snapshots

Una comparación muestra crecimiento y reducción entre dos estados.

antes = tracemalloc.take_snapshot()
ejecutar_escenario()
despues = tracemalloc.take_snapshot()

for diferencia in despues.compare_to(antes, "lineno")[:10]:
    print(diferencia)

Repite el escenario para separar warm-up de crecimiento continuo.

Baseline después del warm-up

Imports, caches de bytecode, pools e inicialización lazy crean asignaciones legítimas.

Ejecuta una fase de calentamiento y captura la referencia cuando el sistema esté estable.

Detecta crecimiento repetido

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

gc.collect() puede reducir ruido de diagnóstico, pero no representa necesariamente producción.

Filtros

Filter y DomainFilter incluyen o excluyen traces.

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

No filtres dependencias demasiado pronto; pueden ser el origen real.

Filtros inclusivos y exclusivos

Un filtro exclusivo elimina coincidencias y uno inclusivo conserva solo las compatibles.

Documenta patrones para que el informe sea reproducible.

Tracebacks de asignación

Las APIs de trace permiten inspeccionar frames registrados para bloques individuales.

Las estadísticas agregadas suelen ser más útiles que listar millones de traces.

Guarda y carga snapshots

Los snapshots pueden persistirse.

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

El archivo puede revelar paths y nombres internos. Protégelo como artefacto de diagnóstico.

Usa linecache en informes

Recupera el código fuente para enriquecer la salida.

import linecache

frame = estadistica.traceback[0]
linea = linecache.getline(frame.filename, frame.lineno).strip()

Consulta linecache en Python.

Inicia antes de imports

Opciones del intérprete o una variable de entorno pueden activar tracing antes del código de aplicación.

Ayuda con startup, pero produce más ruido.

Overhead

Guardar tracebacks consume CPU y memoria. El coste crece con la cantidad de frames.

En producción, usa ventanas cortas, una instancia de diagnóstico o un procedimiento controlado.

Memoria rastreada frente a RSS

RSS puede continuar alto después de liberar objetos porque allocators conservan arenas y el sistema administra páginas.

Una caída en bytes rastreados sin caída de RSS no prueba un leak. Analiza tendencias.

Memoria nativa

NumPy, imágenes, compresión, drivers y extensiones C pueden asignar fuera de los dominios visibles.

Si RSS crece y tracemalloc permanece estable, usa profilers nativos y métricas específicas.

Objetos vivos y referencias

tracemalloc muestra dónde se asignó memoria, no necesariamente por qué el objeto sigue vivo.

Combínalo con gc, inspección de referencias y análisis de caches.

Leaks frente a caches

Un cache puede crecer por diseño, pero sin límite se convierte en leak operacional.

Revisa tamaño máximo, expiración, cardinalidad de claves y eviction.

Threads

El tracing es global al proceso. Las asignaciones de varias threads aparecen en los mismos snapshots.

Sincroniza el escenario para comparar fases equivalentes.

Procesos

Cada proceso posee su propio estado de tracemalloc.

En multiprocessing, recopila snapshots o métricas por worker y agrega externamente. No confundas un worker con el total del servicio.

Tests de regresión

Un test puede repetir un escenario y verificar que el crecimiento neto quede bajo un margen.

Evita límites rígidos: versión de Python, plataforma e imports cambian números exactos. Usa tendencias y tolerancia.

Mide una función

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

No detengas un tracing que pertenece a otro componente.

clear_traces

clear_traces() elimina traces registrados sin cambiar objetos vivos.

Úsalo para iniciar una fase limpia, sabiendo que pierdes el historial anterior.

stop

stop() desactiva el rastreo y limpia estado interno según la versión.

Los snapshots ya creados pueden seguir analizándose.

Informes útiles

Incluye archivo, línea, fuente, tamaño, diferencia, cantidad y media. Muestra unidades legibles, pero conserva bytes para cálculos.

Destaca los mayores crecimientos en vez de mostrar miles de entradas.

Seguridad y privacidad

Paths y líneas pueden revelar nombres de clientes, directorios internos y lógica propietaria.

Redacta datos antes de adjuntar informes a tickets públicos.

Observabilidad

tracemalloc es principalmente una herramienta de diagnóstico, no una métrica continua de alta frecuencia.

Monitoriza RSS, contadores de objetos y caches; activa snapshots cuando las tendencias indiquen problema.

Pruebas

Prueba un escenario estable, crecimiento intencional, liberación, cache limitado, varias threads y procesos separados.

Controla warm-up, usa entrada determinística y repite para reducir ruido.

Errores comunes

Los fallos frecuentes son confundir memoria rastreada con RSS, capturar baseline antes del warm-up, usar un solo snapshot, filtrar dependencias pronto, ignorar memoria nativa, guardar demasiados frames en producción y asumir que todo crecimiento es leak.

Conclusión

tracemalloc muestra dónde Python asigna memoria y cómo cambia el perfil. Usa snapshots comparables, filtros documentados, picos por fase y escenarios repetidos.

Combina resultados con RSS, garbage collector y métricas nativas. Consulta la documentación oficial de tracemalloc, linecache en Python y la guía para detectar fugas de memoria.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código en un monitor que representa acceso a memoria nativa con ctypes.memoryview_at en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ctypes.memoryview_at: memoria nativa sin copias

    Aprende ctypes.memoryview_at en Python para acceder a memoria nativa sin copias, validar punteros y reducir riesgos.

    Ler mais

    Tempo de leitura: 7 minutos
    12/10/2026
    Código Python en pantalla representando EnumDict y enumeraciones avanzadas
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    EnumDict: personaliza Enums con validación

    Aprende EnumDict en Python para personalizar EnumType, validar miembros y crear enumeraciones avanzadas con seguridad.

    Ler mais

    Tempo de leitura: 4 minutos
    11/10/2026
    Rack de servidores que representa el balanceo de conexiones con SO_REUSEPORT_LB en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: reparte conexiones entre workers

    Aprende SO_REUSEPORT_LB en Python para distribuir conexiones entre workers con pruebas, portabilidad y cierre ordenado.

    Ler mais

    Tempo de leitura: 5 minutos
    11/10/2026
    Código Python asíncrono en un portátil para inspect.markcoroutinefunction
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    markcoroutinefunction: detecta wrappers async

    Aprende inspect.markcoroutinefunction en Python para identificar wrappers asíncronos, integrar frameworks y evitar detecciones incorrectas.

    Ler mais

    Tempo de leitura: 5 minutos
    10/10/2026
    Código Python para recorrer carpetas y archivos con Path.walk
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Path.walk: recorre directorios con seguridad

    Aprende Path.walk en Python para recorrer directorios, filtrar archivos, tratar errores y controlar la travesía con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    10/10/2026
    Depuración de un proceso Python en terminal con código
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depura procesos Python en ejecución

    Aprende a conectar pdb a un proceso Python en ejecución, inspeccionar la pila y diagnosticar bloqueos de forma segura.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026