Android High Memory Pressure: как диагностировать и исправить ошибки

Android High Memory Pressure: как диагностировать и исправить ошибки

6 апреля 2022 г.

Память — один из самых важных ресурсов вашего приложения для Android. Платформа Android старается держать в памяти как можно больше приложений, даже когда они не используются. Это не просто кеш файлов, из которых состоит ваше приложение, а работающий процесс приложения и его потоки. Такое поведение позволяет быстро переключаться между приложениями и задачами и позволяет конечным пользователям чувствовать себя «быстро». Однако на младших устройствах все может начать запутываться, если работающее приложение занимает больше своей справедливой доли памяти. Результатом этой ситуации является увеличение того, что называется «давлением памяти».


Вы можете думать о нехватке памяти как о основном приложении, с которым взаимодействует пользователь, вытесняя другие приложения из памяти. Это процесс, и он не происходит сразу или все время. Вместо этого платформа Android (в частности Low Memory Killer или LMK) будет предпринимать дополнительные шаги, пытаясь освободить больше оперативной памяти для памяти. -голодное приложение переднего плана.


В какой-то степени, невиданной на других платформах, Android в значительной степени состоит из экосистемы взаимозависимых приложений, взаимодействующих друг с другом с помощью общей памяти или межпроцессного взаимодействия (IPC). Многие классы обслуживания, которые вы получаете с помощью Context.getSystemService на самом деле являются упрощенными фасадами, которые взаимодействуют с системные сервисные процессы с использованием IPC. Это создает удивительно взаимосвязанную систему, в которой приложения могут безопасно и беспрепятственно обмениваться данными и ресурсами, а весь опыт становится для конечного пользователя «больше, чем сумма его частей». Это также может привести к непредвиденным и трудным для отладки проблемам со стабильностью.


Как нехватка памяти влияет на стабильность приложения


Итак, как нехватка памяти влияет на стабильность вашего приложения? Самый распространенный и очевидный ответ — ошибки Out Of Memory, но на Android возможны и несколько других случаев. Если ваше приложение находится на переднем плане, то завершаются другие приложения, а если ваше приложение находится в фоновом режиме, пользователь не заметит, если оно будет убито, верно? Неправильно.


Ваше приложение может быть завершено, потому что другие приложения потребляют слишком много памяти, и если ваше приложение в это время выполняет какую-либо работу (резервное копирование, синхронизация с сервером, очистка кеша и т. д.), вы можете получить отчет о сбое, который не по-видимому, связано с памятью.


Другая ситуация с памятью, которая может вызвать проблемы, — это когда ваше приложение закрывается, когда пользователь переходит от одного приложения к другому. Например, при обмене фотографией с другим приложением или при переходе на страницу справки, размещенную в Chrome. Если памяти недостаточно для одновременного хранения обоих приложений, Android завершит работу приложения в фоновом режиме и восстановит его, когда пользователь вернется обратно. Поначалу это не кажется проблемой, но вашему приложению может потребоваться холодный запуск, что приведет к значительным задержкам и потенциально [Приложение не отвечает] (https://developer.android.com/topic/performance/vitals/anr) (ANR) сообщает, что система пытается перезапустить ваше приложение и выгрузить предыдущее. Это может быть еще хуже в таких случаях использования, как обмен контентом. Например, отправка фотографии из вашего замечательного приложения для редактирования фотографий другу через приложение для обмена сообщениями.


Сквозная отчетность по памяти в Bugsnag


Отчеты об ошибках на Android недавно были обновлены. Начиная с версии 5.12.0 мы добавили несколько новых параметров, о которых мы автоматически сообщаем на вашу панель управления.


Bugsnag делит отчеты о памяти на две существующие категории метаданных: приложение и устройство. [Свойства памяти приложения] (https://docs.bugsnag.com/platforms/android/automatically-captured-data/#application-information) относятся к вашему приложению, а [Свойства устройства] (https://docs .bugsnag.com/platforms/android/customizing-error-reports/#device) помогут вам понять, что еще происходит на устройстве в тот же момент времени. Мы делим эти поля на две основные категории (как и многие другие поля, которые мы собираем): приложение (относится к вашему приложению) и устройство (относится к устройству, на котором работало ваше приложение, когда создавался отчет).


На вкладке «Приложение» на панели инструментов Bugsnag мы сообщаем:


  • общая память

Общий объем памяти, доступный в настоящее время для вашего приложения, сообщается непосредственно из Runtime.totalMemory. Точное определение этого значения варьируется от одного устройства к другому, но его значение остается неизменным: это то, сколько места занимают ваши объекты Java/Kotlin в зависимости от платформы. Обычно сюда входит некоторая неиспользуемая (свободная) память, которую можно использовать для выделения новых объектов без увеличения кучи.


  • freeMemory
    Объем доступной памяти, не используемой в настоящее время объектами Java/Kotlin, сообщается непосредственно из Runtime.freeMemory. Это то, сколько места могут использовать новые объекты, прежде чем сборщик мусора должен быть запущен или будет выделено больше места в куче.

  • memoryUsage
    Значение для удобства сообщается как totalMemory - freeMemory. Это оценка того, сколько памяти использовало ваше приложение при создании отчета.

  • memoryLimit
    Максимальный объем памяти, который Android позволит вашему приложению использовать для объектов Java/Kotlin, сообщается непосредственно из Runtime.maxMemory. Указанное здесь значение будет сильно различаться в зависимости от конфигурации устройства и конкретной версии Android. Некоторые устройства сообщают значение, близкое к объему установленной оперативной памяти, в то время как другие сообщают значения всего 8 МБ.

  • lowMemory
    Сообщала ли платформа вашему приложению о ситуации с нехваткой памяти до создания отчета. Это значение получено из более подробного memoryTrimLevel и предоставляется в основном для обратной совместимости.

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


На вкладке «Устройство» мы сообщаем:


  • totalMemory
    Как написано на коробке: общий объем памяти, доступный устройству. Это немного зависит от конфигурации устройства и версии Android, но чаще всего это объем физически установленной оперативной памяти.

  • freeMemory
    Объем памяти, который Android считал «свободным» при создании отчета. Часто это довольно мало, так как Android будет хранить большие объемы кэшированных данных в памяти, что не считается «бесплатным».


Уровень ограничения памяти


Одно существенное изменение заключается в том, что теперь мы отслеживаем Memory Trim Level на вкладке "Приложение" как для отчетов JVM, так и для отчетов NDK. Это позволяет вам увидеть, о каком нехватке памяти в последний раз сообщалось вашему приложению:



Этот атрибут является самым последним значением, переданным вашему приложению с помощью onTrimMemory, что дает ценную информацию о том, почему это распределение Bitmap не удалось, или почему ваше приложение было прекращено. Мы также начали автоматически собирать хлебные крошки при доставке этих событий, поэтому вы будете иметь представление о памяти давление, ведущее к отчету о сбое.


Вкладка «Устройство» также содержит четкое представление о ситуации с памятью для физического устройства, включая объем установленной оперативной памяти (totalMemory) и объем этой памяти, который считается свободным и доступным (freeMemory). Информация о том, сколько ОЗУ доступно на устройстве, может дать ценную информацию, когда пользователю удалось вывести из строя функцию, требовательную к памяти, в вашем приложении.


Не все ошибки стоит исправлять. Исправьте только те, которые имеют значение.


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



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE