Утечки памяти в Android

Плохо, когда объект остаётся в памяти дольше, чем это реально нужно. Ведь используемые ресурсы пригодятся для решения других задач, которые могут иметь для пользователей не меньшую ценность. Давайте посмотрим, почему утечки памяти в Android-приложениях — это плохо. И заодно разберём, как обнаружить утечки памяти.

Почему утечки памяти нежелательны?

Во-первых, когда происходят утечки, становится меньше памяти, доступной для использования. Это, в свою очередь, приводит к более частым запускам сборщика мусора. Частые запуски приостанавливают рендеринг пользовательского интерфейса, плюс приводят к остановке прочих компонентов, нужных для нормальной работы системы. В результате прорисовка кадра длится дольше обычных 16 мс. И если этот показатель становится порядка 100 мс, пользователи начинают замечать замедления в работе Android-приложений.

Скорость отклика приложений контролируют как менеджер активности, так и менеджер окон. При этом система открывает для приложения диалог ANR (Android Not Responding) в том случае, когда выполняется одно из двух условий: — приложение не отвечает на нажатия в течение 5 секунд; — BroadcastReceiver не завершается в течение 10 секунд.

Разумеется, никому не понравится наблюдать данное сообщение на экранах своего девайса.

Вторая проблема заключается в том, что приложение с утечкой памяти не получает дополнительные ресурсы от неиспользуемых объектов. Да, будет выполняться запрос на выделение дополнительной памяти, но в определённый момент система перестанет выделять дополнительную память, и приложение упадёт.

Результат объяснять не надо — клиенты недовольны, отзывы негативны, приложение удаляется пользователем.

Определяем утечку памяти в Android-приложениях

Для определения утечки вы должны понимать работу сборщика мусора. Кроме того, вам помогут инструменты, позволяющие определять возможные утечки либо просто находить подозрительные участки кода.

Один из таких инструментов — Leak Canary от Square. Инструмент создаёт ссылки на объекты вашего Android-приложения, а также проверяет удаляются ли данные ссылки сборщиком мусора. Если ссылки не удаляются, информация заносится в файл .hprof, после чего выполняется анализ наличия утечек памяти. Когда утечка обнаружится, вы получите соответствующее сообщение. Однако помните, что рекомендуется использовать Leak Canary до выпуска вашего приложения в production.

Второй инструмент для поиска утечек памяти, который стоит упомянуть, входит в Android Studio. Если вы подозреваете, что часть кода является причиной утечек, выполните следующие действия: 1) скомпилируйте и запустите отладочную версию сборки на эмуляторе либо устройстве, подключённому к вашему ПК; 2) перейдите к подозрительной операции, а потом вернитесь к предыдущему действию, чтобы вывести подозрительную операцию из стека задач; 3) откройте в Android Studio "Android Monitor window → Memory section" и нажмите на клавишу запуска сборщика мусора (Initiate GC). Потом нажмите кнопку «Dump Java Heap»;

4) далее откроется файл .hprof. Есть несколько вариантов проверки утечки с помощью этого файла. Например, для автоматического поиска используйте Analyzer Tasks (находится в правом верхнем углу). Также можно переключиться в режим Tree View, чтобы найти действие, которое нужно будет отключить. Если после проверки данных Total Count вы найдёте отличия в данных, значит, где-то есть утечка.

5) Обнаружив утечку памяти, останется проверить дерево ссылок, чтобы понять, какой объект вызывает утечку.

Удачной вам разработки!

Материал написан на основе статьи «[Memory Leak Patterns in Android (https://android.jlelse.eu/memory-leak-patterns-in-android-4741a7fcb570)».