Утечка памяти Python: найдите буфер, удерживающий объекты
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Память Python: задачи на tracemalloc, утечки и slots.
Локализация удерживающего буфера
Фоновый конвейер принимает партии сообщений, преобразует их в рабочие структуры данных и перекладывает результат в целевую очередь. Стенд работает без видимых сбоев, но в процессе непрерывной обработки потребление памяти монотонно возрастает. Профилирование с помощью tracemalloc точно указывает на строку внутри функции трансформации, где создаются проблемные объекты. При этом сама функция чиста: порождённые ею экземпляры не задерживаются локально, а незаметно оседают в одном из глобальных буферов — кэше дедупликации, отладочном журнале ошибок, очереди повторов или реестре сессий.
Чтобы выяснить, какая именно коллекция удерживает лишние данные, исследовательская утилита поочерёдно очищает подозрительные структуры. После каждого такого действия инструмент делает контрольный снимок памяти и сопоставляет освобождённый объём с исходной строкой аллокации.
Определите имя удерживающего контейнера, очистка которого привела к реальному освобождению памяти, выделенной проблемной строкой.
Что уже дано
В редакторе представлена сигнатура функции find_retaining_container(containers, allocation_site).
При выполнении кода доступны вспомогательные инструменты:
make_retention_probe(names, owner, ...)— готовит испытательный стенд с реальными буферами под управлениемtracemalloc;observe_retention_probe(probe)— запускает диагностику и возвращает отчёт с контрольными снимками;make_retention_example()— создаёт готовый типовой сценарий.
Служебный параметр owner используется только стендом для наполнения буферов и в диагностическую функцию не передаётся. Реализовывать эти вспомогательные функции самостоятельно не требуется.
Что нужно сделать
Реализуйте функцию find_retaining_container(containers, allocation_site).
Функция принимает два аргумента:
containers— отображение (dictили аналогичный mapping), сопоставляющее строковые имена буферов с 2–6 изменяемыми коллекциями (list,dictили их стандартные подклассы). В каждом заполненном буфере находится от 2 до 16 объектов размером от 64 до 8192 байт (отвлекающие аллокации в других буферах могут быть до 8 раз крупнее);allocation_site— кортеж вида(filename, lineno), гдеfilename(str) — имя файла, аlineno(int) — положительный номер строки, в которой фактически происходило выделение памяти под проблемные объекты.
Требования к поведению:
- Выполните серию контрольных экспериментов: очищайте проверяемые коллекции по отдельности и фиксируйте реальное изменение занятой памяти через контрольные снимки
tracemalloc.take_snapshot(). - Определите буфер, освобождение которого приводит к фактическому уменьшению объёма памяти, аллоцированной в точке
allocation_site. - Функция должна вернуть имя удерживающего контейнера в виде строки (
strили совместимого строкового типа). - Не требуется вычислять процентные доли, абсолютные пороги байтов, оценивать системный RSS процесса или восстанавливать очищенные коллекции после проведения замеров.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня find_retaining_container и вызывает её с проверочными аргументами.
Пример использования
names = ('dedup_cache', 'error_log', 'retries')
for owner in ('dedup_cache', 'error_log'):
probe = make_retention_probe(names, owner)
observed = observe_retention_probe(probe)
print(observed['result'])
Вывод:
dedup_cache error_log
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- slots в Python: за счёт чего экономится память
- Наследование и slots в Python: почему возвращается dict
- Tracemalloc Python: группировка выделений памяти по стеку вызовов
- slots в Python: проверка полей и всей иерархии наследования
- Удаление ключа из ChainMap в Python: проверка поведения del
- Обратный индекс на Python: группировка уникальных значений через defaultdict
