Профилирование памяти с tracemalloc
Отслеживайте выделение памяти и находите утечки с помощью tracemalloc.
«Профилирование памяти с tracemalloc» — бесплатный урок Python Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
Что такое tracemalloc
tracemalloc — это модуль стандартной библиотеки, который отслеживает выделения памяти Python по имени файла и номеру строки.
import tracemalloc
tracemalloc.start()
x = [i for i in range(100_000)]
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Current: {current/1024:.1f} KB")
print(f"Peak: {peak/1024:.1f} KB")Создание снимков
Снимок фиксирует все текущие выделения памяти в определённый момент времени. Сравните два снимка, чтобы узнать, что было выделено между ними.
import tracemalloc
tracemalloc.start()
snap1 = tracemalloc.take_snapshot()
data = [{"key": str(i)} for i in range(10_000)]
snap2 = tracemalloc.take_snapshot()
stats = snap2.compare_to(snap1, "lineno")
for stat in stats[:5]:
print(stat)Фильтрация снимков
Отфильтруйте статистику, чтобы показывать только код вашего приложения, исключив стандартную библиотеку.
import tracemalloc
tracemalloc.start()
leak_function()
snap = tracemalloc.take_snapshot()
filters = [tracemalloc.Filter(True, "*/myapp/*")]
stats = snap.filter_traces(filters).statistics("lineno")
for stat in stats[:10]:
print(stat)Основные источники выделений памяти
Используйте snapshot.statistics("lineno") или "traceback", чтобы увидеть основные потребители памяти по строкам или по полной трассировке стека.
import tracemalloc
tracemalloc.start(nframe=10) # track 10 frames deep
big_list = [i**2 for i in range(500_000)]
snap = tracemalloc.take_snapshot()
for stat in snap.statistics("traceback")[:3]:
print(stat)
for line in stat.traceback.format():
print(" ", line)Поиск утечек памяти
Сделайте два снимка до и после места, где предполагается утечка, и сравните их. Рост показателей между снимками указывает на утечку.
import tracemalloc
tracemalloc.start()
snap_before = tracemalloc.take_snapshot()
for _ in range(100):
suspected_leaky_function()
snap_after = tracemalloc.take_snapshot()
diff = snap_after.compare_to(snap_before, "lineno")
for stat in diff[:5]:
print(stat)get_traced_memory()
tracemalloc.get_traced_memory() возвращает количество байт в формате (current, peak) — это удобно для лёгких проверок до и после.
import tracemalloc
tracemalloc.start()
before, _ = tracemalloc.get_traced_memory()
do_something()
after, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Delta: {(after-before)/1024:.1f} KB, Peak: {peak/1024:.1f} KB")memory_profiler
memory_profiler показывает использование памяти для каждой строки, подобно тому как line_profiler показывает использование CPU.
# pip install memory_profiler
from memory_profiler import profile
@profile
def build_data():
data = [i**2 for i in range(100_000)]
filtered = [x for x in data if x % 2 == 0]
return filtered
build_data()
# python -m memory_profiler script.pymemray
memray от Bloomberg — это быстрый профилировщик памяти Python с выводом в виде пламенной диаграммы.
# pip install memray
# python -m memray run script.py
# python -m memray flamegraph memray-script.py.bin
# Generates an interactive HTML flamegraph
# showing allocations by call stackСнижение использования памяти
Распространённые методы: используйте генераторы вместо списков, __slots__, модуль array для числовых данных и массивы NumPy, а также не удерживайте крупные объекты в замыканиях.
# Instead of:
data = [process(x) for x in huge_list] # all in memory
# Use a generator:
def gen_data(lst):
for x in lst:
yield process(x)
for item in gen_data(huge_list):
consume(item) # one at a timesys.getsizeof()
sys.getsizeof(obj) возвращает объём памяти объекта в байтах (поверхностный размер — без учёта объектов, на которые он ссылается).
import sys
print(sys.getsizeof([])) # 56
print(sys.getsizeof([1,2,3])) # 88
print(sys.getsizeof("hello")) # 54
print(sys.getsizeof({})) # 64
# For deep size, use recursive measurement:
def deep_size(obj):
return sys.getsizeof(obj) + sum(
sys.getsizeof(v) for v in vars(obj).values()
if hasattr(obj, "__dict__")
)Профилирование в рабочей среде
В рабочей среде запускайте tracemalloc с ограниченным числом кадров трассировки, чтобы свести накладные расходы к минимуму. Сохраняйте снимки в файл для автономного анализа.
import tracemalloc, pickle
tracemalloc.start(nframe=5) # low overhead
# ... serve some requests ...
snap = tracemalloc.take_snapshot()
with open("snap.pkl","wb") as f:
pickle.dump(snap, f)
# Analyse later offlineБыстрая проверка
Что обозначают два значения, возвращаемые tracemalloc.get_traced_memory()?
Итоги
Используйте tracemalloc.start() и снимки, чтобы находить утечки памяти. Сравнивайте снимки с помощью compare_to(). Используйте memory_profiler для построчного анализа использования памяти, а memray — для пламенных диаграмм. Снижайте расход памяти с помощью генераторов, __slots__ и массивов NumPy.
Часто задаваемые вопросы
Урок «Профилирование памяти с tracemalloc» бесплатный?
Да — полный текст урока «Профилирование памяти с tracemalloc» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «Профилирование памяти с tracemalloc»?
Отслеживайте выделение памяти и находите утечки с помощью tracemalloc. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Профилирование памяти с tracemalloc»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Подсчёт ссылок в CPython
- Сборщик мусора и циклические ссылки
- Профилирование с cProfile и line_profiler
- Профилирование памяти с tracemalloc