0Pricing
Python Academy · Урок

Профилирование памяти с 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.py

memray

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 time

sys.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 — локальная установка не требуется.

Все уроки этого курса

  1. Подсчёт ссылок в CPython
  2. Сборщик мусора и циклические ссылки
  3. Профилирование с cProfile и line_profiler
  4. Профилирование памяти с tracemalloc
← Назад к Python Academy