Использование памяти для растровых изображений

Растровые изображения часто являются самыми большими объектами, потребляющими больше всего памяти в приложении. Операции декодирования и масштабирования часто находятся на критическом пути для рендеринга кадров. Оптимизация использования памяти для растровых изображений обеспечивает значительное улучшение отзывчивости пользовательского интерфейса, времени автономной работы и общей стабильности за счет уменьшения рывков, ошибок ANR и завершений процессов, связанных с нехваткой памяти.

Выявление случаев чрезмерного использования памяти для растровых изображений.

Android Vitals предоставляет метрики по объему используемой приложением памяти, агрегируя данные с устройств Android. Эти метрики включают процентили за определенный период (например, 28 дней) для каждого пакета и процесса. Эти данные помогают выявлять тенденции и потенциальные регрессии в эффективности использования памяти на разных типах и версиях устройств.

Android Vitals отображает использование памяти, предназначенной для отображения растровых изображений, в разбивке по следующим состояниям процесса :

  • В фоновом режиме : процесс приложения виден. Ожидается, что показатель P99 будет значительно выше в фоновом режиме по сравнению с другими состояниями процесса, но разработчикам следует проверить, является ли соотношение P99/P50 значительным (например, выше 3,5x), поскольку это часто указывает на утечку памяти в битовой карте. Это можно определить, наблюдая расхождение между типичным использованием (P50) и аномальным использованием (P99); в то время как общее раздувание ресурсов равномерно увеличивает объем памяти по всем процентилям, утечки памяти накапливаются со временем, сильно искажая данные в конце процесса (P99). Убедитесь, что выделение битовой карты в фоновом режиме не сохраняется без необходимости после перехода приложения в другие состояния.
  • Воспринимаемые пользователем службы : процесс приложения находится в воспринимаемом пользователем состоянии. Это включает в себя службы переднего плана , ускоренные задачи и задачи передачи данных, инициированные пользователем . Приложения не должны сохранять большие объемы выделенной памяти для битовых карт переднего плана при переходе в эти состояния. Поскольку эти службы предназначены для длительных задач, сохранение больших объемов данных ухудшает общее впечатление от использования и заставляет демон LMKD (Low Memory Killer Daemon) освобождать память, завершая процессы с более низким приоритетом.
  • Фоновый режим : Приложение работает в фоновом режиме или недавно было переведено в фоновый режим, но еще не кэшировано. Поскольку это состояние процесса менее важно, чем состояние процессов переднего плана или видимых процессов, приложениям следует явно освобождать большие растровые изображения именно в этот момент, чтобы снизить нагрузку на память.
  • Кэшированное состояние : Приложение находится в кэшированном состоянии. Это состояние очень чувствительно к нагрузке на системную память, например, из-за LMK-сообщений. Приложения должны заблаговременно сокращать использование памяти для растровых изображений в этом состоянии, чтобы избежать вытеснения данных операционной системой.

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

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

Ресурсы

Анализ растровых изображений в Android Studio

Профилирование растровых изображений в Android Studio

Используйте профилировщик памяти для проверки выделения памяти в режиме реального времени, создания дампов кучи и анализа объектов на предмет утечек памяти; кроме того, используйте анализатор кучи для обнаружения утечек памяти, выявления дублирующих выделений битовых карт и визуализации времени хранения объектов.

Автоматическое обнаружение утечек с помощью LeakCanary

Интегрируйте библиотеку LeakCanary для автоматического обнаружения утечек памяти в вашем приложении. LeakCanary обеспечивает автоматический анализ кучи, выявляя объекты, которые должны были быть удалены сборщиком мусора, но все еще находятся в памяти, например, битовые карты, сохраненные после уничтожения Activity или Fragment.

Документация по производительности растровых изображений

Эти ресурсы содержат исчерпывающие рекомендации по передовым методам эффективной обработки растровых изображений в различных компонентах Android.

Контрольный список для разработчиков по оптимизации использования памяти для растровых изображений.

Для оптимизации использования памяти для растровых изображений следуйте трем основным принципам: сокращение, повторное использование и переработка.

  • Уменьшить : Свести к минимуму объем памяти, занимаемый файлами при загрузке или отображении растровых изображений.
  • Повторное использование : Внедрите механизмы кэширования, чтобы избежать избыточного выделения памяти для битовых карт.
  • Перезагрузка : Заблаговременное высвобождение ресурсов для перераспределения памяти для активных процессов.

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

Основной принцип Область Описание
Уменьшать Удалите повторяющиеся растровые изображения. Проанализируйте дампы памяти с помощью профилировщика памяти, чтобы обнаружить избыточное выделение памяти для битовых карт. См. руководство по управлению памятью для битовых карт .
Используйте библиотеки для загрузки изображений. Используйте такие библиотеки, как Glide и Coil , для автоматизации многопоточности, кэширования и эффективного декодирования.
Внедрить понижение разрешения Декодировать изображения таким образом, чтобы они соответствовали размерам целевого контейнера пользовательского интерфейса, вместо загрузки ресурсов в полном разрешении.
Для непрозрачных изображений используйте RGB_565. Сократите объем используемой памяти на 50% за счет перехода с формата ARGB_8888 на 16-битную конфигурацию для изображений без прозрачности.
Приоритет отдается векторным изображениям. Используйте векторную графику для значков и базовых графических элементов , чтобы обеспечить четкое масштабирование с минимальными затратами памяти.
Оптимизация доставки изображений на стороне сервера. Настройте бэкэнд API для предоставления изображений, адаптированных под плотность экрана устройства и размеры ImageView.
Устранить прозрачные поля Избегайте выделения памяти для «невидимых» пикселей, используя InsetDrawable или отступы макета вместо встроенных полей. См. раздел «Разработка приложений Android с высокой производительностью памяти» .
Повторное использование Настройка оптимальных размеров кэша Настройте ограничения памяти и дискового кэша в зависимости от объема оперативной памяти устройства и разрешения экрана. См. раздел «Кэширование растровых изображений» .
Переработка Очистка ресурсов в фоновом режиме Реализуйте TRIM_MEMORY_BACKGROUND для очистки кэша и повышения выживаемости процессов при нехватке системной памяти.
Освобождайте ресурсы, когда пользовательский интерфейс скрыт. Используйте TRIM_MEMORY_UI_HIDDEN для освобождения кэша растровых изображений, когда приложение перестаёт быть видимым для пользователя.
Мониторинг утечек памяти Используйте LeakCanary и Memory Profiler для поиска битовых карт, сохранившихся после уничтожения их LifecycleOwner. См. раздел «Управление памятью вашего приложения» .