Запись выделений Java/Kotlin, Запись выделений Java/Kotlin

Запись распределения 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++.

Проверьте запись о распределении

Чтобы проверить запись распределения, выполните следующие действия:

  1. Просмотрите список классов на вкладке «Таблица» , чтобы найти объекты с необычно большими значениями «Выделения» или «Общее количество» (в зависимости от того, для чего вы оптимизируете) и которые могут стать причиной утечки.
  2. На панели «Просмотр экземпляра» щелкните экземпляр. В зависимости от того, что применимо к этому экземпляру, откроется вкладка «Поля» или «Стек вызовов распределения» . Используйте информацию на вкладках «Поля» или «Стек вызовов распределения», чтобы определить, действительно ли экземпляры необходимы или дублируются ненужно.

Щелкните правой кнопкой мыши любую запись списка, чтобы перейти к соответствующему исходному коду.

Просмотр глобальных ссылок JNI

Java Native Interface (JNI) — это платформа, которая позволяет коду Java и собственному коду вызывать друг друга. Ссылки JNI управляются вручную с помощью собственного кода, поэтому могут возникнуть следующие проблемы:

  • Объекты Java, используемые собственным кодом, сохраняются слишком долго.
  • Некоторые объекты в куче Java могут стать недоступными, если ссылка JNI отбрасывается без предварительного явного удаления.
  • Глобальный лимит ссылок JNI исчерпан.

Чтобы устранить такие проблемы, выберите «Просмотреть кучу JNI» в профилировщике, чтобы просмотреть все глобальные ссылки JNI и отфильтровать их по типам Java и собственным стекам вызовов. Щелкните правой кнопкой мыши поле экземпляра на вкладке «Поля» и выберите «Перейти к экземпляру», чтобы просмотреть соответствующий стек вызовов распределения.

На вкладке «Стек вызовов распределения» показано, где в вашем коде выделяются и освобождаются ссылки JNI.

Дополнительную информацию о JNI см. в разделе Советы по JNI .