Android: управляем памятью
У каждого разработчика наступает момент, когда ему кажется, что он освоил язык программирования, но приложение тормозит и отладчик не помогает. Это значит, что ему нужно расширять круг своих познаний, выйти из привычной среды разработки и оценить происходящее извне.
Начните управлять памятью. Да, это сложно поначалу, но память компьютера и мобильного девайса — ресурс ограниченный, и научившись им распоряжаться, удается одним махом решить целый спектр проблем.
Управление памятью в 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».