Tracemalloc Python: группировка выделений памяти по стеку вызовов
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Память Python: задачи на tracemalloc, утечки и slots.
Разметка прироста памяти
Потоковый синтаксический анализатор разбирает текстовые пакеты и формирует токены с помощью общей вспомогательной функции. К ней обращаются разные прикладные ветки: парсер заголовков, парсер тела и парсер метаданных. Чтобы отслеживать расход памяти, система ведёт диагностику с глубиной стека больше единицы: для каждого выделения фиксируется цепочка кадров tracemalloc.Frame. Однако сами эти кадры хранят только имя файла и номер строки, поэтому сопоставить системные замеры с архитектурой программы можно лишь по заранее заданной карте ответственности — таблице соответствия пар (filename, lineno) текстовым меткам контекстов.
Инспектор памяти отбирает записи StatisticDiff со строгим положительным приростом (size_diff > 0) и раскручивает цепочку кадров от точки аллокации вверх к вызывающим функциям. Поиск продолжается до первого совпадения кадра с картой ответственности. Если совпадение найдено, весь прирост памяти из этой записи начисляется указанному контексту; если же ни один кадр трассировки не попал в карту, запись относится к категории неразмеченных аллокаций.
Определите суммарный положительный прирост памяти для каждого размеченного контекста и найдите метку контекста с наибольшей нагрузкой.
Что уже дано
При выполнении кода доступны вспомогательные функции make_attribution_probe, make_attribution_example и observe_attribution_case, генерирующие реальные объекты tracemalloc.StatisticDiff и карту кадров. В редакторе требуется реализовать только саму функцию attribute_allocations.
Что нужно сделать
Реализуйте функцию attribute_allocations(differences, responsibility).
Функция принимает два аргумента:
differences— список объектовtracemalloc.StatisticDiff(от 0 до 2000 записей со значениямиsize_diffпо модулю до 10 000 000 байт и глубиной трассировки от 1 до 16 кадров);responsibility— словарь, сопоставляющий пары(filename, lineno)строковым меткам контекстов длиной от 1 до 64 символов (от 0 до 100 кадров). Несколько кадров могут ссылаться на одну и ту же метку.
Правила агрегации:
- Учитываются только записи со строгим положительным приростом (
size_diff > 0). Записи с нулевым или отрицательнымsize_diffполностью игнорируются. - Для каждой подходящей записи обход кадров выполняется по цепочке трассировки
item.tracebackот места непосредственного выделения вверх к вызывающему коду. Весь объёмsize_diffприписывается первой встретившейся вresponsibilityпаре(frame.filename, frame.lineno). - Если ни один кадр трассировки не найден в
responsibility, значениеsize_diffдобавляется к категории неразмеченной памятиunmarked. - Значения
size_diffповторных аллокаций и цепочек суммируются для соответствующих контекстов.
Функция возвращает словарь ровно с тремя ключами:
"totals"— словарьdict[str, int], содержащий ключи для абсолютно всех уникальных меток изresponsibility. Если для контекста не было подходящих аллокаций, его сумма равна0;"unmarked"— целое число (int), суммарный объём положительного прироста памяти записей, у которых ни один кадр не совпал с картой ответственности;"leader"— любая метка контекста изresponsibilityс максимальным значением вtotals(при равенстве максимумов допустима любая из лидирующих меток). Значение равноNoneстрого тогда, когда вresponsibilityнет ни одной метки. Категорияunmarkedв определении лидера не участвует.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня attribute_allocations и вызывает её с проверочными аргументами.
Пример использования
differences, responsibility = make_attribution_example()
report = attribute_allocations(differences, responsibility)
print(report['leader'])
print(report['unmarked'])
Вывод:
headers 0
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- slots в Python: за счёт чего экономится память
- Наследование и slots в Python: почему возвращается dict
- Утечка памяти Python: найдите буфер, удерживающий объекты
- slots в Python: проверка полей и всей иерархии наследования
- Удаление ключа из ChainMap в Python: проверка поведения del
- Обратный индекс на Python: группировка уникальных значений через defaultdict
