← Назад к вопросам
К чему приводят нюансы работы с памятью в Python
1.7 Middle🔥 121 комментариев
#Архитектура и паттерны#Тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Нюансы работы с памятью в Python и их последствия
Python имеет ряд особенностей управления памятью, которые нередко приводят к утечкам, неожиданному поведению и проблемам с производительностью. Я столкнулся с этими проблемами много раз в production коде.
1. Циклические ссылки и сборка мусора
Проблема
class Node:
def __init__(self):
self.parent = None
self.children = []
parent = Node()
child = Node()
parent.children.append(child)
child.parent = parent # Циклическая ссылка!
del parent # Объект НЕ удалится, пока не запустится GC
Следствие
- Утечки памяти: объекты остаются в памяти дольше, чем нужно
- Замедление: GC (сборка мусора) должна обнаруживать циклы
- Неопределённое время жизни: когда точно удалится объект, неизвестно
Решение
import weakref
class Node:
def __init__(self):
self.parent = None
self.children = []
parent = Node()
child = Node()
parent.children.append(child)
child.parent = weakref.ref(parent) # Слабая ссылка
del parent # Объект удалится сразу
2. Глобальные переменные и кэши
Проблема
cache = {} # Глобальный кэш в модуле
def process_user(user_id):
if user_id not in cache:
user = fetch_from_db(user_id)
cache[user_id] = user
return cache[user_id]
# После обработки 1 млн пользователей кэш занимает ГБ памяти
Следствие
- Неконтролируемый рост памяти: кэш растёт до бесконечности
- Стейл данные: кэш может содержать устаревшую информацию
- Утечки в долгоживущих процессах: в worker-процессах, daemon-потоках
Решение
from functools import lru_cache
@lru_cache(maxsize=1000)
def process_user(user_id):
return fetch_from_db(user_id)
3. Замыкания и утечки переменных
Проблема
def create_handlers():
handlers = []
for i in range(1000):
big_data = [0] * 1_000_000
handlers.append(lambda x: big_data[0] + x)
return handlers
handlers = create_handlers()
# Все 1000 обработчиков хранят ссылку на big_data!
Решение
def create_handlers():
handlers = []
for i in range(1000):
big_data = [0] * 1_000_000
handlers.append(lambda x, val=big_data[0]: val + x)
del big_data
return handlers
4. Слоты вместо dict
Проблема
class User:
pass
users = [User() for _ in range(1_000_000)]
# Каждый объект имеет __dict__, даже если атрибутов нет
Решение
class User:
__slots__ = ["id", "name", "email"]
def __init__(self, id, name, email):
self.id = id
self.name = name
self.email = email
5. Неправильная работа с файлами
Проблема
def process_files():
files = [open(f"file_{i}.txt") for i in range(1000)]
# Забыли закрыть файлы!
Решение
def process_files():
for i in range(1000):
with open(f"file_{i}.txt") as f:
data = f.read()
6. Потоковая обработка больших данных
Проблема
with open("huge_file.csv") as f:
lines = f.readlines() # 5 GB в памяти!
Решение
with open("huge_file.csv") as f:
for line in f:
process(line)
Итоги
Нюансы памяти приводят к утечкам, деградации производительности и ошибкам в production. Самые частые проблемы — циклические ссылки, глобальные кэши и неправильная работа с ресурсами.