Запись распределения Java/Kotlin помогает выявить нежелательные шаблоны памяти, которые могут вызывать проблемы с производительностью. Профилировщик может показать вам следующее о распределении объектов:
- Какие типы объектов были выделены и сколько места они занимают.
- Трассировка стека каждого выделения, включая поток.
- Когда объекты были освобождены.
Вам следует записывать выделение памяти во время обычного и интенсивного взаимодействия с пользователем, чтобы точно определить, где ваш код либо выделяет слишком много объектов за короткое время, либо выделяет объекты, которые стали утечкой. Узнайте больше о том, почему вам следует профилировать память приложения .
Как записывать распределения Java/Kotlin
Чтобы записать выделения Java/Kotlin, выберите задачу «Отслеживать потребление памяти (распределения Java/Kotlin)» на вкладке «Главная» профилировщика. Обратите внимание, что вам нужно отлаживаемое приложение (используйте Profiler: запустите «приложение» как отлаживаемое (полные данные) ) для записи выделений Java/Kotlin.
Android Studio по умолчанию фиксирует все выделения объектов в памяти. Если у вас есть приложение, которое выделяет много объектов, вы можете наблюдать видимые замедления работы вашего приложения во время профилирования. Чтобы повысить производительность при профилировании, перейдите в раскрывающийся список «Отслеживание распределения» и выберите «Выборочное» вместо «Полное» . При выборке профилировщик собирает информацию о выделениях объектов в памяти через регулярные промежутки времени.
Чтобы принудительно выполнить сбор мусора во время записи, щелкните значок мусора .
Обзор распределений Java/Kotlin
После остановки записи вы увидите следующее:
- На временной шкале событий отображаются состояния активности, события пользовательского ввода и события поворота экрана.
- Временная шкала использования памяти показывает следующую информацию. Выберите часть временной шкалы для фильтрации по определенному диапазону времени.
- Составной график, показывающий, сколько памяти используется каждой категорией памяти, как показано осью Y слева и цветовой клавишей вверху.
- Пунктирная линия указывает количество выделенных объектов, как указано по оси Y справа.
- Значок для каждого события сбора мусора.
- На вкладке «Таблица» отображается список классов. Общее количество — это количество выделений в конце выбранного диапазона времени ( Выделения минус Освобождения ), поэтому может иметь смысл сначала отладить классы, которые имеют самые высокие значения общего количества . Если вас больше интересуют классы устранения неполадок на основе пиковых выделений в течение выбранного диапазона времени, расставьте приоритеты по Распределениям . Аналогично, оставшийся размер — это размер выделения минус размер освобождения в байтах.
- Если щелкнуть класс в списке «Таблица» , откроется панель «Экземпляр» со списком связанных объектов, включая время их выделения, время освобождения и их небольшой размер .
На вкладке «Визуализация» отображается совокупное представление всех объектов в стеке вызовов за выбранный диапазон времени. По сути, он показывает, сколько общей памяти занимает стек вызовов с показанными экземплярами. В первой строке отображается имя потока. По умолчанию объекты располагаются слева направо в зависимости от размера выделения; используйте раскрывающийся список, чтобы изменить порядок.
Используйте раскрывающийся список кучи, чтобы отфильтровать определенные кучи. В дополнение к фильтрам, доступным при записи дампа кучи , вы можете фильтровать классы в куче JNI, куче, которая показывает, где ссылки на собственный интерфейс Java (JNI) выделяются и освобождаются.
Используйте раскрывающийся список расположения, чтобы выбрать способ распределения. В дополнение к механизмам, доступным при захвате дампа кучи , вы можете организовать его с помощью стека вызовов.
Как считается память
Числа, которые вы видите вверху, основаны на всех страницах частной памяти, зафиксированных вашим приложением, в соответствии с системой Android. В это число не входят страницы, которыми поделились система или другие приложения. Категории в подсчете памяти следующие:
- Java : память объектов, выделенных из кода Java или Kotlin.
Native : память объектов, выделенных из кода C или C++.
Даже если вы не используете C++ в своем приложении, вы можете увидеть, что здесь используется некоторая встроенная память, поскольку платформа Android использует встроенную память для выполнения различных задач от вашего имени, например, при обработке ресурсов изображений и другой графики, даже если код, который вы Я написал на Java или Kotlin.
Графика : память, используемая для очередей графического буфера для отображения пикселей на экране, включая поверхности GL, текстуры GL и т. д. Обратите внимание, что это память, используемая совместно с ЦП, а не выделенная память графического процессора.
Стек : память, используемая как собственным стеком, так и стеком Java в вашем приложении. Обычно это связано с количеством потоков, выполняемых вашим приложением.
Код : память, которую ваше приложение использует для кода и ресурсов, таких как байт-код DEX, оптимизированный или скомпилированный код DEX, .
so
библиотеки, и шрифты.Другое : память, используемая вашим приложением, которую система не знает, как классифицировать.
Выделено : количество объектов Java/Kotlin, выделенных вашим приложением. При этом не учитываются объекты, выделенные в C или C++.
Проверьте запись о распределении
Чтобы проверить запись распределения, выполните следующие действия:
- Просмотрите список классов на вкладке «Таблица» , чтобы найти объекты с необычно большими значениями «Выделения» или «Общее количество» (в зависимости от того, для чего вы оптимизируете) и которые могут стать причиной утечки.
- На панели «Просмотр экземпляра» щелкните экземпляр. В зависимости от того, что применимо к этому экземпляру, откроется вкладка «Поля» или «Стек вызовов распределения» . Используйте информацию на вкладках «Поля» или «Стек вызовов распределения», чтобы определить, действительно ли экземпляры необходимы или дублируются ненужно.
Щелкните правой кнопкой мыши любую запись списка, чтобы перейти к соответствующему исходному коду.
Просмотр глобальных ссылок JNI
Java Native Interface (JNI) — это платформа, которая позволяет коду Java и собственному коду вызывать друг друга. Ссылки JNI управляются вручную с помощью собственного кода, поэтому могут возникнуть следующие проблемы:
- Объекты Java, используемые собственным кодом, сохраняются слишком долго.
- Некоторые объекты в куче Java могут стать недоступными, если ссылка JNI отбрасывается без предварительного явного удаления.
- Глобальный лимит ссылок JNI исчерпан.
Чтобы устранить такие проблемы, выберите «Просмотреть кучу JNI» в профилировщике, чтобы просмотреть все глобальные ссылки JNI и отфильтровать их по типам Java и собственным стекам вызовов. Щелкните правой кнопкой мыши поле экземпляра на вкладке «Поля» и выберите «Перейти к экземпляру», чтобы просмотреть соответствующий стек вызовов распределения.
На вкладке «Стек вызовов распределения» показано, где в вашем коде выделяются и освобождаются ссылки JNI.
Дополнительную информацию о JNI см. в разделе Советы по JNI .