Aller au contenu

Commandes Memray

Memray est un profileur mémoire pour Python développé par Bloomberg. Il suit chaque allocation mémoire dans le code Python et les extensions C/C++, fournissant des informations détaillées sur l’utilisation mémoire via des flame graphs, des tableaux et un suivi en temps réel.

Installation

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 — Enregistrement des allocations

# Profiler un script Python
memray run my_script.py

# Profiler avec des arguments
memray run my_script.py --arg1 --arg2 value

# Profiler un module
memray run -m pytest tests/

# Fichier de sortie personnalisé
memray run -o my_profile.bin my_script.py

# Suivre les allocations natives (C/C++)
memray run --native my_script.py

# Suivre les processus enfants (fork/exec)
memray run --follow-fork my_script.py

# Suivre uniquement les allocateurs Python (plus rapide, moins détaillé)
memray run --trace-python-allocators my_script.py

# Forcer l'écrasement du fichier de sortie existant
memray run --force -o profile.bin my_script.py

# Profiler avec seuil mémoire maximum (mode agrégé)
memray run --aggregate my_script.py

memray flamegraph — Flame graphs mémoire

# Générer un flame graph HTML depuis un enregistrement
memray flamegraph my_profile.bin

# Fichier de sortie personnalisé
memray flamegraph -o memory_flamegraph.html my_profile.bin

# Afficher les allocations temporaires (libérées pendant le profilage)
memray flamegraph --temporary-allocations my_profile.bin

# Afficher uniquement les allocations supérieures à un seuil
memray flamegraph --temporary-allocation-threshold 1024 my_profile.bin

# Filtrer uniquement les fuites (allocations jamais libérées)
memray flamegraph --leaks my_profile.bin

# Fusionner les threads dans une seule vue
memray flamegraph --merge-threads my_profile.bin

memray table — Rapport tabulaire

# Générer un tableau HTML des allocations
memray table my_profile.bin

# Fichier de sortie personnalisé
memray table -o allocation_table.html my_profile.bin

# Afficher les allocations temporaires
memray table --temporary-allocations my_profile.bin

# Afficher uniquement les allocations avec fuites
memray table --leaks my_profile.bin

memray tree — Arbre d’appels

# Générer un rapport d'arbre d'appels
memray tree my_profile.bin

# Afficher les plus grosses allocations en premier
memray tree --biggest-allocs 20 my_profile.bin

# Afficher les allocations temporaires
memray tree --temporary-allocations my_profile.bin

memray summary — Résumé des allocations

# Afficher un résumé de haut niveau des allocations
memray summary my_profile.bin

memray stats — Statistiques détaillées

# Afficher les statistiques détaillées d'allocation
memray stats my_profile.bin

# La sortie inclut :
# - Total des allocations et désallocations
# - Utilisation mémoire maximale
# - Répartition par allocateur (malloc, calloc, realloc, etc.)
# - Principales locations d'allocation
# - Chronologie mémoire

Mode de suivi en direct

# Démarrer une session de suivi en direct (TUI temps réel)
memray run --live my_script.py

# Suivi en direct avec connexion distante
# Terminal 1 : Démarrer le processus profilé
memray run --live-remote --live-port 12345 my_script.py

# Terminal 2 : Se connecter à la session en direct
memray live 12345

# Suivi en direct d'un module
memray run --live -m flask run

Suivi des allocations natives

# Suivre les allocations des extensions C/C++ (numpy, pandas, etc.)
memray run --native my_script.py

# Générer un flame graph montrant les cadres natifs
memray flamegraph my_profile.bin
# Les cadres natifs apparaissent dans le flame graph aux côtés des cadres Python

# Le suivi natif est essentiel pour :
# - Utilisation mémoire NumPy/SciPy
# - Allocations DataFrame Pandas
# - Fuites mémoire des extensions C
# - Allocations des modules Cython

Détection de fuites

# Enregistrer et trouver les fuites
memray run -o leak_check.bin my_script.py

# Générer un flame graph des fuites uniquement
memray flamegraph --leaks leak_check.bin -o leaks.html

# Générer un tableau des fuites uniquement
memray table --leaks leak_check.bin -o leaks_table.html

# Générer une vue arbre des fuites uniquement
memray tree --leaks leak_check.bin

Plugin pytest

# Installer le plugin memray pour pytest (inclus avec memray)
pip install memray

# Exécuter les tests avec contrôle de limite mémoire
pytest --memray tests/

# Définir une limite mémoire par test (échoue si dépassée)
pytest --memray --memray-bin-path=./profiles tests/

# Utiliser le marqueur dans les 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()
# Marqueurs pytest pour les limites mémoire
import pytest

# Échouer le test s'il utilise plus de 100 Mo
@pytest.mark.limit_memory("100 MB")
def test_memory_usage():
    data = load_large_dataset()
    result = process(data)
    assert result is not None

# Échouer le test s'il a des fuites de plus de 512 Ko
@pytest.mark.limit_leaks("512 KB")
def test_no_memory_leaks():
    conn = create_connection()
    conn.execute("SELECT 1")
    conn.close()

Analyse de la sortie

Lecture des Flame Graphs

# Interprétation du flame graph mémoire :
# - Largeur axe X = proportion du total de mémoire allouée
# - Profondeur axe Y = pile d'appels (bas = entrée, haut = site d'allocation)
# - Boîtes plus larges = plus de mémoire allouée via ce chemin de code
# - Clic pour zoomer, recherche pour mettre en surbrillance des fonctions
# - Les couleurs distinguent les cadres Python des cadres natifs

Patterns courants

# Trouver ce qui alloue le plus de mémoire
memray flamegraph my_profile.bin
# Chercher les boîtes les plus larges en haut du flame graph

# Trouver les allocations temporaires (rotation d'allocations)
memray flamegraph --temporary-allocations my_profile.bin
# Les allocations temporaires causent de la pression sur le GC

# Trouver les fuites mémoire
memray flamegraph --leaks my_profile.bin
# Les allocations en fuite ne sont jamais libérées pendant le profilage

# Comparer mémoire maximale vs. mémoire finale
memray stats my_profile.bin
# Grande différence entre max et final suggère des pics temporaires

Utilisation avancée

# Profiler avec le mode agrégé (overhead réduit, moins de détails)
memray run --aggregate my_script.py

# Combiner avec d'autres profileurs
# 1. Utiliser memray pour la mémoire, py-spy pour le CPU
memray run -o mem.bin my_script.py &
py-spy record -o cpu.svg --pid $!

# Profiler un notebook Jupyter
# Dans une cellule du notebook :
# %load_ext memray
# %memray_flamegraph
# result = expensive_function()

# Transformer la sortie binaire en différents formats
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

Dépannage

# "Error: only Linux is supported" — Memray fonctionne uniquement sous Linux
# Utiliser Docker sur macOS/Windows :
# docker run -it --rm -v $(pwd):/app python:3.11 bash
# pip install memray && memray run /app/my_script.py

# Cadres natifs manquants — compiler les extensions avec les infos de débogage
CFLAGS="-g" pip install numpy

# Fichiers de sortie volumineux — utiliser le mode agrégé
memray run --aggregate -o compact.bin my_script.py

# Le profilage se bloque — s'assurer qu'il n'y a pas de lecture stdin dans le script profilé
memray run --force my_script.py < /dev/null

Référence rapide

CommandeFonction
memray runEnregistrer les allocations mémoire
memray flamegraphGénérer un flame graph HTML interactif
memray tableGénérer un tableau HTML des allocations
memray treeAfficher l’arbre d’appels des allocations
memray summaryRésumé de haut niveau des allocations
memray statsStatistiques détaillées des allocations
memray run --liveSuivi en temps réel par TUI
memray run --nativeInclure les allocations C/C++
--leaksFiltrer les allocations en fuite uniquement
--temporary-allocationsAfficher les allocations libérées