Привет, Хабр! Около полугода назад я опубликовал подробное «руководство» по JVM .
Пост в целом был принят хорошо, и в комментариях спросили, планируется ли «что-то для Android».
Наконец я дошел до этого.
В этом посте мы поговорим о среде выполнения в Android. В частности, я попытаюсь кратко, но емко обрисовать, чем отличаются ART и Dalvik и как с течением времени совершенствовались инструменты разработки под Android. Тема явно не новая, но надеюсь, она пригодится тем, кто только начинает в ней вникать.
Если кому интересно, добро пожаловать под кат.
Виртуальная машина
Для начала давайте разберемся, чем JVM отличается от DVM. Виртуальная машина Java — это виртуальная машина, способная выполнять байт-код Java независимо от базовой платформы.Он основан на принципе «Напиши один раз, работай где угодно».
Байт-код Java можно запускать на любой машине, поддерживающей JVM. Компилятор Java преобразует файлы .
java в файлы классов (байт-код).
Байт-код передается JVM, которая компилирует его в машинный код для выполнения непосредственно на ЦП.
Возможности JVM:
- Он имеет стековую архитектуру: стек используется как структура данных, в которой размещаются и хранятся методы.
Работает по схеме LIFO или «Последний пришёл – первый ушёл».
- Может запускать только файлы классов.
- Использует JIT-компилятор.
Каждый процесс выполняется в своем изолированном адресном пространстве.
Когда пользователь запускает приложение (или операционная система запускает один из его компонентов), ядро виртуальной машины Dalvik (Zygote Dalvik VM) создает в общей памяти отдельный защищенный процесс, в котором сама виртуальная машина развертывается как среда для запуска приложение.
Другими словами, изнутри Android выглядит как набор виртуальных машин Dalvik, на каждой из которых выполняется приложение.
Возможности DVM:
- Использует архитектуру на основе регистров: структура данных, в которой размещаются методы, основана на регистрах процессора.
Из-за отсутствия операций POP и PUSH команды в виртуальной машине с регистром выполняются быстрее, чем аналогичные команды в виртуальной машине на основе стека.
- Исполняет собственный формат байт-кода: Android dexer (мы поговорим об этом ниже) преобразует файлы классов в формат .
dex, оптимизированный для выполнения на Dalvik VM. В отличие от файла классов, файл dex содержит сразу несколько классов.
Вы можете прочитать больше об архитектуре DVM. здесь .
Андроид Дексер
Разработчики Android знают, что процесс преобразования байт-кода Java в байт-код .dex для среды выполнения Android является ключевым шагом в создании APK. Компилятор dex в основном работает «под капотом» при повседневной разработке приложений, но он напрямую влияет на время сборки приложения, размер файла .
dex и производительность во время выполнения.
Как уже говорилось, сам dex-файл содержит сразу несколько классов.
Повторяющиеся строки и другие константы, используемые в нескольких файлах классов, включены только для экономии места.
Байт-код Java также преобразуется в альтернативный набор команд, используемый DVM. Несжатый файл dex обычно на несколько процентов меньше по размеру, чем сжатый Java-архив (JAR), полученный из тех же файлов .
class. Первоначально файлы классов были преобразованы в файлы dex с помощью встроенного компилятора DX. Но начиная с Андроид Студия 3.1 и далее компилятором по умолчанию стал Д8 .
По сравнению с компилятором DX, D8 компилируется быстрее и создает файлы dex меньшего размера, обеспечивая при этом лучшую производительность приложения во время выполнения.
Полученный таким образом байт-код dex минифицируется с помощью утилиты с открытым исходным кодом.
ПроГард .
В результате мы получаем тот же dex-файл, но только меньшего размера.
Этот dex-файл затем используется для создания apk и его окончательного развертывания на устройстве Android.
Но после D8 в 2018 пришел Р8 , который по сути является тем же D8, только с дополнениями.
При запуске плагина Android Studio 3.4 и Android Gradle 3.4.0 или более поздней версии Proguard больше не используется для оптимизации кода во время компиляции.
Вместо этого плагин по умолчанию работает с R8, который сам выполняет сжатие, оптимизацию и обфускацию кода.
Хотя R8 предлагает только часть функций, предоставляемых Proguard, он позволяет завершить процесс преобразования байт-кода Java в байт-код dex за один раз, что еще больше сокращает время сборки.
R8 и сокращение кода
Обычно приложения используют сторонние библиотеки, такие как Jetpack, Gson, Google Play Services. Когда мы используем одну из этих библиотек, часто в приложении используется лишь небольшая часть каждой отдельной библиотеки.Без сжатия кода весь библиотечный код сохраняется в вашем приложении.
Бывает, что разработчики используют подробный код, чтобы улучшить читабельность и удобство сопровождения приложения.
Например, можно использовать осмысленные имена переменных и шаблоны проектирования, чтобы облегчить понимание кода другими.
Но шаблоны, как правило, приводят к созданию большего количества кода, чем необходимо.
В этом случае на помощь приходит R8. Это позволяет вам значительно уменьшить размер вашего приложения, оптимизируя размер даже того кода, который фактически используется приложением.
В качестве примера ниже приведены цифры из отчета Уменьшение вашего приложения с помощью R8 , который был представлен на Android Dev Summit '19:
А вот как выглядело сравнение эффективности R8 на этапе выпуска бета-версии (взято из источника Блог разработчиков Android ):
Более подробную информацию можно найти в документации И отчет .
ART против DVM в Android
DVM был разработан специально для мобильных устройств и использовался в качестве виртуального машина для запуска приложений Android до Android 4.4 Kitkat. Начиная с этой версии, ИСКУССТВО был представлен как среда выполнения, а в Android 5.0 (Lollipop) ART полностью заменил Dalvik. Основное очевидное различие между ART и DVM заключается в том, что ART использует компиляцию AOT, а DVM использует JIT-компиляцию.Недавно ART начала использовать гибрид AOT и JIT. Далее давайте рассмотрим это немного подробнее.
ДВМ
- Использует JIT-компиляцию: при каждом запуске приложения
- компилируется часть кода, необходимая для запуска приложения.
Остальная часть кода компилируется динамически.
Это замедляет запуск и работу приложений, но сокращает время установки.
- Ускоряет загрузку устройства, поскольку кэш приложения создается во время выполнения.
- Приложениям, работающим на DVM, требуется меньше памяти, чем приложениям, работающим на ART.
- Уменьшает запас батареи, увеличивая нагрузку на процессор.
- Dalvik «устарел» и не используется на версиях Android выше 4.4.
ИСКУССТВО
- Использует компиляцию AOT, что означает, что весь код компилируется во время установки приложения.
Это ускоряет запуск и работу приложений, но требует более длительного времени установки.
- Замедляет время загрузки устройства, поскольку кеш создается во время первой загрузки.
- Из-за использования подхода компиляции AOT требуется больше памяти по сравнению с приложениями на DVM.
- Увеличивает запас батареи за счет уменьшения работы процессора из-за отсутствия компиляции при запуске приложений.
- Улучшенная сборка мусора или сбор мусора.
При использовании Dalvik сборщикам мусора приходилось делать 2 прохода по куче, что приводило к ухудшению UX. В случае с ART такой ситуации нет: он очищает кучу один раз для консолидации памяти.
И небольшая диаграмма Dalvik vs ART:
JIT + AOT в ART
Среда выполнения Android (ART), начиная с Android 7, включает JIT-компилятор с профилированием кода.JIT-компилятор дополняет компилятор AOT и повышает производительность во время выполнения, экономит дисковое пространство и ускоряет обновления приложений и системы.
Это происходит по следующей схеме:
Вместо запуска AOT-компиляции каждого приложения во время установки оно запускает приложение под управлением виртуальной машины с помощью JIT-компилятора (почти так же, как в Android).
< 5.0), but keeps track of which parts of the application code are executed most often .
This information is then used to AOT compile these code sections. The last operation is performed only when the smartphone is idle while charging. Говоря простым языком, сейчас вместе работают два совершенно разных подхода, что дает свои преимущества:
- более эффективная компиляция — при запуске приложения в реальном времени компилятор может узнать гораздо больше о его работе, чем при выполнении статического анализа, и, как следствие, для каждой ситуации применяются более подходящие методы оптимизации;
- сохранение оперативной и постоянной памяти — байт-код более компактен, чем машинный код, и если выполнять AOT-компиляцию только отдельных разделов приложения и не компилировать приложения, которые пользователь не использует, можно существенно сэкономить пространство NAND-памяти;
- резкое увеличение скорости установки и первой загрузки после обновления системы - никакой AOT-компиляции, никакой задержки.
Заключение
В этой статье я попытался рассмотреть основные различия между Dalvik и ART и в целом взглянуть на то, как Android с течением времени улучшала инструменты разработки.ART все еще находится в стадии разработки, и добавляются новые функции, улучшающие работу как пользователей, так и разработчиков.
Если было полезно, дайте знать в комментариях.
Теги: #Android #Разработка Android #Разработка мобильных приложений #java #среда выполнения Android #dalvik
-
Мактаггарт, Джон
19 Oct, 24 -
Как Я Писал В Scad
19 Oct, 24