Какие методы профилирования и поиска утечек памяти существуют
Что проверяют
Знаете ли вы инструменты и понимаете ли, что искать надо не абсолютный расход, а невозвращённую память.
Как отвечать
Инструменты:
- Instruments: набор шаблонов. Аллокации показывают рост и живые объекты, отдельный шаблон ищет недостижимую, но не освобождённую память, есть профилирование процессора и кадров анимации;
- отладчик графа памяти в Xcode: снимок всех живых объектов со связями. Показывает кто держит объект, и это обычно и есть ответ. Умеет подсвечивать циклы;
- зомби-объекты: обращение к уже освобождённому объекту вместо неопределённого поведения даёт понятное сообщение;
- журналирование стека выделений для ответа на вопрос, откуда взялся конкретный объект;
- метрики из прода в разделе организации: расход памяти и завершения по её нехватке у реальных пользователей.
Метод, который важнее инструментов. Абсолютное число мегабайт мало о чём говорит. Правильная проверка выглядит так: зафиксировать базовый уровень, выполнить сценарий несколько раз подряд (открыть и закрыть экран, прокрутить список, вернуться назад) и посмотреть, возвращается ли память к исходному значению. Ступенчатый рост от повтора к повтору это утечка, ровное плато это нормальное поведение.
Типичные причины утечек в iOS:
- цикл сильных ссылок через делегата или через замыкание, хранимое тем же объектом, на который оно ссылается;
- подписка на уведомления или наблюдение, которые не сняли;
- таймер, удерживающий цель;
- кэш без ограничения размера;
- срез коллекции, удерживающий исходный буфер целиком.
Отдельно стоит различать утечку и разрастание: во втором случае объекты достижимы и формально не утекли, просто их никто не удаляет. Инструмент поиска утечек их не покажет, а память кончится одинаково.
Где спотыкаются
Смотрят только пиковый расход и не проверяют возврат к базовому уровню.
Ищут утечки на симуляторе, где поведение памяти отличается.
Полагаются только на автоматический поиск утечек и пропускают разрастание кэшей.
Не снимают наблюдателей и таймеры.