dex2oat Конвертировать файл DEX в OAT Симлинк на: файл /apex/com.android.art/bin/dex2oat32 Тип файла: команда usage: dex2oat [options]... Пример: --dex-file=/system/framework/core.jar Пример: --zip-fd=5 Пример: --oat-file=/system/framework/boot.oat Пример: --oat-file=/system/framework/boot.oat Пример: --oat-symbols=/symbols/system/framework/boot.oat Пример: --bitcode=/system/framework/boot.bc Пример: --image=/system/framework/boot.art Пример: --image=frameworks/base/preloaded-classes Пример: --base=0x50000000 Пример: --boot-image=/system/framework/boot.art Default: <host-prefix>/system/framework/boot.art Пример: --host-prefix=out/target/product/crespo Default: $ANDROID_PRODUCT_OUT Пример: --android-root=out/host/linux-x86 Default: $ANDROID_ROOT Пример: --instruction-set=x86 Default: arm Пример: --instruction-set=Portable Default: Quick таких как начальный размер кучи, максимальный размер кучи и подробный вывод. Используйте отдельный ключ --runtime-arg для каждого аргумента. Пример: --runtime-arg -Xms256m Комментарии Для понимания принципа работы Baseline profile нужно вспомнить виды компиляции в Android. После сборки приложения мы получаем файл .apk, который содержит файлы .dex. В них находится bytecode, понятный интерпретатору. Android runtime транслирует bytecode в машинный код. Получение машинного кода из bytecode может происходить несколькими путями. В случае с Dalvik девайсы производились с небольшой по объему оперативной памятью (RAM), поэтому шаги по оптимизации были нацелены на уменьшение ее использования. Для этого использовалась JIT (Just-In-Time) compilation — компиляция в runtime. Вместо того чтоб компилировать все приложение целиком, компилировались лишь некоторые участки кода. Так как вся компиляция происходит в процессе выполнения, это негативно сказывалось на производительности. На замену Dalvik пришел ART с измененным подходом к компиляции. В ART появилась компиляция AOT (Ahead of time). К моменту запуска приложения весь код уже скомпилирован. Как результат, получаем выигрыш по производительности, но просадку по использованию RAM, долгую установку приложения и долгие системные обновления. Частичная компиляция является компромиссом. По умолчанию bytecode JIT-прекомпилируется, но если встречаются участки кода, которые используются часто, тогда они AOT-компилируются. AOT-компиляция происходит при помощи утилиты dex2oat, сохраняя результат в бинарных файлах .oat. В итоге получаем гибридную схему компиляции. Однако и эта схема имеет проблемы. AOT-компиляция происходит спустя какое-то время (после нескольких запусков приложения и прохождения ряда пользовательских сценариев). Поэтому первый опыт и впечатления могут быть подпорчены невысоким уровнем производительности. А ведь зачастую именно первый опыт формирует отношение пользователя к приложению. Поэтому в ART появились профили (profiles). Доступны два вида профилей. Первый — облачный. В процессе использования приложения Google собирает и анализирует сценарии выполнения программы, находит часто используемые участки и отправляет эту информацию на сервер. Эти данные усредняют по множеству пользователей, и получается единый профиль, который попадет новым пользователям для AOT-компиляции при первой установке. Второй вид — Baseline profile. Это возможность указать компилятору те участки кода, которые бы вы хотели прекомпилировать на девайсах пользователей. Эти профили как раз и формируют начальный кеш, который позволяет ускорить время запуска и производительность. Из исходного текста dex2oat.cc: Примечания по чередованию создания образа и файла OAT для Примечания по чередованию создания образа и файла OAT, чтобы гарантировать правильность ссылок между ними. В настоящее время у нас есть макет памяти, который выглядит примерно так: +--------------+ | образ | +--------------+ | boot oat | +--------------+ | выделенное пространство | +--------------+ Существует несколько ограничений на загрузку образа и boot.oat. 1. Ожидается, что образ будет загружен по абсолютному адресу и содержит объекты с абсолютными указателями внутри образа. 2. Есть абсолютные указатели от методов в образе на их код в OAT. 3. Есть абсолютные указатели из кода в OAT на методы в изображении. 4. Существуют абсолютные указатели от кода в OAT к другому коду в OAT Чтобы все сделать правильно, мы проходим несколько шагов. 1. Мы уже создали этот файл OAT с помощью CreateOatFile. Первоначально это был наш собственный файл, но теперь он содержится в динамическом объекте ELF (также известном как файл .so). Компилятор, возвращаемый CreateOatFile, предоставляет PatchInformation для ссылок на код oat и методы, которые необходимо обновить, как только мы узнаем, где файл oat будет расположен после j,hfpf. 2. Создаем файл образа. Ему необходимо знать, куда после себя будет загружен файл oat. Первоначально файл oat просто отображался в памяти, чтобы мы могли предсказать, где находится его содержимое, на основе размера файла. Теперь, когда это файл ELF, нам нужно проверить файл ELF, чтобы понять структуру сегмента памяти, включая то, где находится заголовок OAT. PatchOatCodeAndMethods ImageWriter использует PatchInformation из компилятора для исправления абсолютных ссылок в файле oat. 3. Мы исправляем заголовки программы ELF, чтобы dlopen пытался загрузить .so в нужное место во время выполнения, смещая значения Elf32_Phdr.p_vaddr на желаемый базовый адрес. |