Android: управляем памятью

Есть ресурсы, которые программист не может увеличить. Значит, ими надо эффективно управлять.
2 минуты14199

У каждого разработчика наступает момент, когда ему кажется, что он освоил язык программирования, но приложение тормозит и отладчик не помогает. Это значит, что ему нужно расширять круг своих познаний, выйти из привычной среды разработки и оценить происходящее извне.

Начните управлять памятью. Да, это сложно поначалу, но память компьютера и мобильного девайса — ресурс ограниченный, и научившись им распоряжаться, удается одним махом решить целый спектр проблем.

Управление памятью в Android

Android основан на Linux, и использует ее нативные библиотеки. Это значит, что ввод-вывод и управление памятью работают на уровне ОС. Но при выполнении прикладного ПО, Android использует собственные Android Runtime (ART) и виртуальную машину. Так же поступают Java и .NET, однако Android пошёл своим путем и самостоятельно управляет жизненным циклом ПО. И это создает некоторые недоразумения.

Каждое приложение Android работает в виде отдельного процесса в рамках виртуальной машины Dalvik, исполняющей приложения, написанные на Java.

Dalvik оптимизирована для низкого потребления памяти, но расплата за это — нестандартная регистр-ориентированная архитектура, подходящая для исполнения на RISC-архитектурах мобильных процессоров. Это в корне отличает её от стандартных виртуальных машин Java. В Android 4.4 Kitkat и выше есть выбор между Dalvik и более быстрым ART, а в Android 5.0 используется только ART.

И Dalvik, и ART — надстройки над ядром Linux, а ведь именно он отвечает за работу с «железом» и памятью на низком уровне. А всем остальным приложениям предоставляется API, что не одно и тоже, что и прямой доступ к ресурсам и приводит к замедлению работы ПО.

Делаем выводы. Начнем с того, что смартфон — прежде всего телефон: львиная доля ресурсов отдана на обслуживание звонков и сообщений, а что осталось, достается прикладным программам.

Разработчик должен помнить об особенностях управления жизненным циклом ПО в Android: поскольку оперативная память ограничена и есть приоритеты в ее использовании, то порой запуск одного приложения означает закрытие другого из-за недостатка памяти с сохранением состояния в ПЗУ. И чем больше приложений запущено, тем чаще станут эти переключения и будет больше время закрытия/восстановления. И каков бы не был чудесен код этого приложения — оно будет подтормаживать.

Утечки памяти и контекст

Типичная ошибка новичков: наставить кучу долгоживущих ссылок на контекст. Вспоминаем: контекст(Context) используется для загрузки и доступа к ресурсам. Эта та самая причина, по который виджеты должны получать параметр Context в конструктор.

Приложения имеют два вида контекста: Activity and Application. Первый — экран с пользовательским интерфейсом, на который держат ссылку в коде и тем самым не дают сборщику мусора удалить отработавший код и данные. Сколько при этом будет потеряно памяти — неизвестно.

А теперь представьте: меняется ориентация экрана, и система по умолчанию уничтожает текущую активность и создает новую с сохранением состояния. Также должен перезагрузиться пользовательский интерфейс приложения. А если в нем содержится большое растровое изображение? Надо принимать меры! Например, использовать статические поля. Но ведь о них не помнят, пока не возьмут в руки девайс со своим приложением!

Правильное использование контекста Application поможет с проблемами: он «жив», пока работает приложение и не зависит от жизненного цикла. Если разработчику нужны долгоживущие объекты, нуждающиеся в контексте, вспомните об Application: Context.getApplicationContext() или Activity.getApplication().

Перечисленными приемами, конечно же, не ограничиваются методики управления памятью. Главное — сборщик мусора должен делать свою работу, а программист не мешать ему работать. Управлять памятью надо в момент написания кода, а не тогда, когда приложение уже запущено! Кроме того, надо помнить об «узких» местах работы с памятью, свойственных архитектуре Android.

Мы же продолжим эту тему и поговорим о том, какие профайлеры в среде разработки или статические анализаторы кода могут помочь.

Тем, кто хочет профессионально разрабатывать под Android, рекомендуем профессию «Разработчик Android».

 

androidуправление памятью
Нашли ошибку в тексте? Напишите нам.
Спасибо,
что читаете наш блог!