Автор: Даниил Коноваленко (Яндекс Go) · Python Channel · Moscow Python Conf++ 2021
Даниил Коноваленко — backend-разработчик в Яндекс Go. В подразделении несколько сотен микросервисов, треть из них написана на Python. Однажды во время дежурства пришёл алерт: один из сервисов занял 91% памяти. Открыв графики — всё выглядело нормально. Открыв на большем масштабе — характерный паттерн: память растёт линейно и никогда не возвращается. После перезапуска — то же самое. Это и есть утечка.
Доклад — детективная история с реальным production-кейсом. Три акта: как утечка выглядит и как её опознать, откуда они берутся в языке с GC, какие инструменты помогают найти и исправить.
Кому смотреть: backend-разработчикам на Python, которые деплоят сервисы в production и уверены что GC за них всё уберёт. После этого доклада — чуть менее уверены, зато знают что делать.
Из этого можно взять в работу: если у вашего сервиса есть метрика потребления памяти — посмотрите на неё на масштабе нескольких дней. Линейный рост без возврата после GC-цикла — сигнал для расследования, а не повод «накинуть памяти и посмотреть».
Коноваленко явно обозначает план в начале: как утечка выглядит (паттерн на графике, признаки), откуда берётся в Python несмотря на GC, и инструменты расследования — что помогло им и что может помочь другим.
Ключевой тезис: GC в Python — циклический сборщик, он собирает объекты без живых ссылок. Но если где-то в коде ссылка удерживается — объект не будет собран. Источниками могут быть кэши без ограничения размера, замыкания, глобальные структуры данных, которые только растут, циклические ссылки с объектами у которых определён __del__.
Тезисы и презентация: https://conf.python.ru/moscow/2021/abstracts/7955