Ir al contenido

Comandos de Memray

Memray es un perfilador de memoria para Python desarrollado por Bloomberg. Rastrea cada asignación de memoria en código Python y extensiones C/C++, proporcionando información detallada sobre el uso de memoria a través de flame graphs, tablas y seguimiento en tiempo real.

Instalación

Linux/Ubuntu

# Install via pip (Linux only — Memray does not support macOS or Windows)
pip install memray

# Install with all optional dependencies
pip install memray[all]

# Install development version
pip install git+https://github.com/bloomberg/memray.git

# Verify installation
memray --version

memray run — Grabación de asignaciones

# Perfilar un script Python
memray run my_script.py

# Perfilar con argumentos
memray run my_script.py --arg1 --arg2 value

# Perfilar un módulo
memray run -m pytest tests/

# Archivo de salida personalizado
memray run -o my_profile.bin my_script.py

# Rastrear asignaciones nativas (C/C++)
memray run --native my_script.py

# Seguir procesos hijos (fork/exec)
memray run --follow-fork my_script.py

# Rastrear solo asignadores de Python (más rápido, menos detalle)
memray run --trace-python-allocators my_script.py

# Forzar sobrescritura del archivo de salida existente
memray run --force -o profile.bin my_script.py

# Perfilar con umbral máximo de memoria (modo agregado)
memray run --aggregate my_script.py

memray flamegraph — Flame graphs de memoria

# Generar un flame graph HTML desde una grabación
memray flamegraph my_profile.bin

# Archivo de salida personalizado
memray flamegraph -o memory_flamegraph.html my_profile.bin

# Mostrar asignaciones temporales (liberadas durante el perfilado)
memray flamegraph --temporary-allocations my_profile.bin

# Mostrar solo asignaciones mayores que un umbral
memray flamegraph --temporary-allocation-threshold 1024 my_profile.bin

# Filtrar solo fugas (asignaciones nunca liberadas)
memray flamegraph --leaks my_profile.bin

# Fusionar hilos en una sola vista
memray flamegraph --merge-threads my_profile.bin

memray table — Informe tabular

# Generar una tabla HTML de asignaciones
memray table my_profile.bin

# Archivo de salida personalizado
memray table -o allocation_table.html my_profile.bin

# Mostrar asignaciones temporales
memray table --temporary-allocations my_profile.bin

# Mostrar solo asignaciones con fugas
memray table --leaks my_profile.bin

memray tree — Árbol de llamadas

# Generar un informe de árbol de llamadas
memray tree my_profile.bin

# Mostrar las asignaciones más grandes primero
memray tree --biggest-allocs 20 my_profile.bin

# Mostrar asignaciones temporales
memray tree --temporary-allocations my_profile.bin

memray summary — Resumen de asignaciones

# Mostrar un resumen de alto nivel de las asignaciones
memray summary my_profile.bin

memray stats — Estadísticas detalladas

# Mostrar estadísticas detalladas de asignaciones
memray stats my_profile.bin

# La salida incluye:
# - Total de asignaciones y liberaciones
# - Uso máximo de memoria
# - Desglose por asignador (malloc, calloc, realloc, etc.)
# - Principales ubicaciones de asignación
# - Línea temporal de memoria

Modo de seguimiento en vivo

# Iniciar una sesión de seguimiento en vivo (TUI en tiempo real)
memray run --live my_script.py

# Seguimiento en vivo con conexión remota
# Terminal 1: Iniciar el proceso perfilado
memray run --live-remote --live-port 12345 my_script.py

# Terminal 2: Conectar a la sesión en vivo
memray live 12345

# Seguimiento en vivo de un módulo
memray run --live -m flask run

Rastreo de asignaciones nativas

# Rastrear asignaciones de extensiones C/C++ (numpy, pandas, etc.)
memray run --native my_script.py

# Generar flame graph mostrando marcos nativos
memray flamegraph my_profile.bin
# Los marcos nativos aparecen en el flame graph junto a los marcos Python

# El rastreo nativo es esencial para:
# - Uso de memoria de NumPy/SciPy
# - Asignaciones de DataFrame de Pandas
# - Fugas de memoria en extensiones C
# - Asignaciones de módulos Cython

Detección de fugas

# Grabar y encontrar fugas
memray run -o leak_check.bin my_script.py

# Generar flame graph solo de fugas
memray flamegraph --leaks leak_check.bin -o leaks.html

# Generar tabla solo de fugas
memray table --leaks leak_check.bin -o leaks_table.html

# Generar vista de árbol solo de fugas
memray tree --leaks leak_check.bin

Plugin de pytest

# Instalar plugin de memray para pytest (incluido con memray)
pip install memray

# Ejecutar tests con control de límite de memoria
pytest --memray tests/

# Establecer un límite de memoria por test (falla si se excede)
pytest --memray --memray-bin-path=./profiles tests/

# Usar el marcador en tests
# @pytest.mark.limit_memory("100 MB")
# def test_data_processing():
#     process_large_dataset()

# @pytest.mark.limit_leaks("1 MB")
# def test_no_leaks():
#     do_something()
# Marcadores pytest para límites de memoria
import pytest

# Fallar test si usa más de 100 MB
@pytest.mark.limit_memory("100 MB")
def test_memory_usage():
    data = load_large_dataset()
    result = process(data)
    assert result is not None

# Fallar test si tiene fugas de más de 512 KB
@pytest.mark.limit_leaks("512 KB")
def test_no_memory_leaks():
    conn = create_connection()
    conn.execute("SELECT 1")
    conn.close()

Análisis de la salida

Lectura de Flame Graphs

# Interpretación del flame graph de memoria:
# - Ancho del eje X = proporción del total de memoria asignada
# - Profundidad del eje Y = pila de llamadas (abajo = entrada, arriba = sitio de asignación)
# - Cajas más anchas = más memoria asignada a través de esa ruta de código
# - Clic para ampliar, buscar para resaltar funciones específicas
# - Los colores distinguen marcos Python de marcos nativos

Patrones comunes

# Encontrar qué asigna más memoria
memray flamegraph my_profile.bin
# Buscar las cajas más anchas en la parte superior del flame graph

# Encontrar asignaciones temporales (rotación de asignaciones)
memray flamegraph --temporary-allocations my_profile.bin
# Las asignaciones temporales causan presión sobre el GC

# Encontrar fugas de memoria
memray flamegraph --leaks my_profile.bin
# Las asignaciones con fugas nunca se liberan durante la ejecución del perfilado

# Comparar memoria máxima vs. memoria final
memray stats my_profile.bin
# Gran diferencia entre máximo y final sugiere picos temporales

Uso avanzado

# Perfilar con modo agregado (menor sobrecarga, menos detalle)
memray run --aggregate my_script.py

# Combinar con otros perfiladores
# 1. Usar memray para memoria, py-spy para CPU
memray run -o mem.bin my_script.py &
py-spy record -o cpu.svg --pid $!

# Perfilar un notebook Jupyter
# En una celda del notebook:
# %load_ext memray
# %memray_flamegraph
# result = expensive_function()

# Transformar salida binaria a diferentes formatos
memray flamegraph profile.bin -o flame.html
memray table profile.bin -o table.html
memray tree profile.bin > tree.txt
memray stats profile.bin > stats.txt

Solución de problemas

# "Error: only Linux is supported" — Memray solo funciona en Linux
# Usar Docker en macOS/Windows:
# docker run -it --rm -v $(pwd):/app python:3.11 bash
# pip install memray && memray run /app/my_script.py

# Marcos nativos faltantes — compilar extensiones con info de depuración
CFLAGS="-g" pip install numpy

# Archivos de salida grandes — usar modo agregado
memray run --aggregate -o compact.bin my_script.py

# El perfilado se cuelga — asegurar que no hay lectura de stdin en el script perfilado
memray run --force my_script.py < /dev/null

Referencia rápida

ComandoPropósito
memray runGrabar asignaciones de memoria
memray flamegraphGenerar flame graph HTML interactivo
memray tableGenerar tabla HTML de asignaciones
memray treeMostrar árbol de llamadas de asignaciones
memray summaryResumen de alto nivel de asignaciones
memray statsEstadísticas detalladas de asignaciones
memray run --liveSeguimiento en tiempo real por TUI
memray run --nativeIncluir asignaciones C/C++
--leaksFiltrar solo asignaciones con fugas
--temporary-allocationsMostrar asignaciones liberadas