Создавайте дампы памяти, чтобы увидеть, какие объекты в вашем приложении используют память в момент создания дампа, и выявлять утечки памяти , или особенности распределения памяти, которые приводят к зависаниям, сбоям и даже аварийным завершениям работы приложения. Создание дампов памяти особенно полезно после длительной пользовательской сессии, когда это может показать объекты, которые все еще находятся в памяти, но которых там быть не должно.
На этой странице описаны инструменты, предоставляемые Android Studio для сбора и анализа дампов памяти. В качестве альтернативы вы можете проверить память вашего приложения из командной строки с помощью dumpsys , а также просмотреть события сборки мусора (GC) в Logcat .
Почему следует профилировать память приложений
Android предоставляет управляемую среду памяти — когда Android определяет, что ваше приложение больше не использует какие-либо объекты, сборщик мусора освобождает неиспользуемую память и возвращает её в кучу. Способ поиска неиспользуемой памяти в Android постоянно совершенствуется, но в какой-то момент во всех версиях Android система должна ненадолго приостановить выполнение вашего кода. В большинстве случаев эти паузы незаметны. Однако, если ваше приложение выделяет память быстрее, чем система может её собрать, может возникнуть задержка, пока сборщик не освободит достаточно памяти для выполнения ваших задач. Задержка может привести к пропуску кадров и заметному замедлению работы приложения.
Даже если ваше приложение не работает медленно, при утечке памяти оно может сохранять её даже в фоновом режиме. Такое поведение может замедлить работу остальной части системы, заставляя её выполнять ненужные операции сборки мусора. В конечном итоге система вынуждена завершить процесс приложения, чтобы освободить память. Затем, когда пользователь возвращается к приложению, процесс приложения должен полностью перезапуститься.
Для получения информации о методах программирования, которые могут уменьшить использование памяти вашим приложением, ознакомьтесь с разделом «Управление памятью вашего приложения» .
Обзор дампа кучи
Чтобы создать дамп кучи, выберите задачу «Анализ использования памяти (дамп кучи)» (используйте профилировщик: запустите приложение в режиме отладки (полные данные) ), чтобы создать дамп кучи. Во время создания дампа кучи объем используемой Java памяти может временно увеличиться. Это нормально, поскольку создание дампа кучи происходит в том же процессе, что и ваше приложение, и требует некоторого объема памяти для сбора данных. После создания дампа кучи вы увидите следующее:

В списке занятий представлена следующая информация:
- Allocations : Количество выделенных памяти в куче.
Нативный размер : Общий объем нативной памяти, используемой этим типом объекта (в байтах). Для некоторых объектов, выделенных в Java, здесь отображается память, поскольку Android использует нативную память для некоторых классов фреймворка, таких как
Bitmap.Небольшой размер : Общий объем памяти Java, используемый этим типом объекта (в байтах).
Сохраняемый размер : Общий размер памяти, сохраняемый для всех экземпляров этого класса (в байтах).
Используйте меню «Куча», чтобы отфильтровать результаты по определенным кучам:
- Куча приложения (по умолчанию) : Основная куча, в которой ваше приложение выделяет память.
- Образ кучи : образ загрузки системы, содержащий классы, предварительно загруженные во время загрузки. Выделенные здесь ресурсы никогда не перемещаются и не удаляются.
- Куча Zygote : Куча с механизмом копирования при записи, из которой в системе Android создается дочерний процесс приложения.
Используйте выпадающее меню «Расположение», чтобы выбрать способ распределения ресурсов:
- Сгруппировать по классу (по умолчанию) : Группирует все выделения памяти на основе имени класса.
- Сгруппировать по пакету : Группирует все выделенные ресурсы на основе имени пакета.
Используйте выпадающее меню «Класс», чтобы отфильтровать классы по группам:
- Все классы (по умолчанию) : Отображает все классы, включая классы из библиотек и зависимостей.
- Показать утечки активности/фрагментов : Отображает классы, вызывающие утечки памяти.
- Показать классы проекта : отображает только классы, определенные вашим проектом.
Щелкните по имени класса, чтобы открыть панель «Экземпляр» . Каждый указанный экземпляр включает в себя следующее:
- Глубина : кратчайшее количество переходов от любого корневого узла сборщика мусора до выбранного экземпляра.
- Нативный размер : Размер этого экземпляра в собственной памяти. Этот столбец отображается только для Android 7.0 и выше.
- Небольшой размер : Размер этого экземпляра в памяти Java.
- Сохраненный размер : Размер памяти, который занимает данный экземпляр (согласно дереву доминирования ).
Щелкните по экземпляру, чтобы отобразить его подробные сведения , включая поля и ссылки . Типы полей и ссылок обычно являются структурированными типами.
массивы
и примитивные типы данных
В Java. Щелчок правой кнопкой мыши по полю или ссылке позволяет перейти к соответствующему экземпляру или строке в исходном коде.
- Поля : Отображает все поля в данном экземпляре.
- Ссылки : Отображает все ссылки на объект, выделенный на вкладке «Экземпляр» .

Обнаружение утечек памяти
Чтобы быстро отфильтровать классы, которые могут быть связаны с утечками памяти, откройте раскрывающийся список классов и выберите «Показать утечки в Activity/Fragment» . Android Studio отобразит классы, которые, по ее мнению, указывают на утечки памяти для экземпляров Activity и Fragment в вашем приложении.
Для более тщательного поиска утечек памяти вручную просмотрите списки классов и экземпляров, чтобы найти объекты с большим значением Retained Size . Ищите утечки памяти, вызванные любой из следующих причин:
- Долгоживущие ссылки на
ActivityилиContextмогут привести к утечке информации о графе композиции Compose (например, оComposeViewи его подкомпонентах). - Утечка данных из объектов состояния Jetpack Compose (
MutableState), держателей состояния или лямбда-функций, которые захватываютContext. - Забыли очистить обработчики событий или наблюдателей в блоке
onDisposeобъектаDisposableEffect. - Нестатические внутренние классы, такие как
Runnable, которые могут содержать экземплярActivity. - Кэши, которые хранят объекты дольше, чем необходимо.
При обнаружении потенциальных утечек памяти используйте вкладки «Поля» и «Ссылки» в разделе «Подробности экземпляра» , чтобы перейти к интересующей вас строке кода или экземпляра.
Инициировать утечки памяти для тестирования
Для анализа использования памяти следует нагрузить код приложения и попытаться вызвать утечки памяти. Один из способов спровоцировать утечки памяти в приложении — дать ему поработать некоторое время, прежде чем проверять кучу. Утечки могут постепенно распространяться на верхние выделенные области в куче. Однако чем меньше утечка, тем дольше нужно запускать приложение, чтобы её обнаружить.
Утечку памяти также можно вызвать одним из следующих способов:
- Поворачивайте устройство из портретного режима в альбомный и обратно несколько раз, находясь в разных состояниях активности. Поворот устройства часто может привести к утечке
Activity(и, следовательно, к утечке дерева Compose UI и связанных с ним деревьев состояний) в приложении, если приложение хранит ссылку наActivityилиContextвнутри асинхронных операций или контейнеров состояний. - Переключайтесь между своим приложением и другим приложением, находясь в разных состояниях активности. Например, перейдите на главный экран, а затем вернитесь в свое приложение.
Экспорт и импорт записи дампа памяти
Вы можете экспортировать и импортировать файл дампа памяти из вкладки «Прошлые записи» в профилировщике. Android Studio сохраняет запись в виде файла .hprof .
В качестве альтернативы, чтобы использовать другой анализатор файлов .hprof , например jhat , необходимо преобразовать файл .hprof из формата Android в формат .hprof Java SE. Для преобразования формата файла используйте инструмент hprof-conv , находящийся в каталоге {android_sdk}/platform-tools/ . Запустите команду hprof-conv с двумя аргументами: исходным именем файла .hprof и местом, куда будет записан преобразованный файл .hprof , включая новое имя файла .hprof . Например:
hprof-conv heap-original.hprof heap-converted.hprof