AOT — що таке Ahead-Of-Time компіляція та як вона працює

Автор: IT Sectr Опубліковано: 2026-04-16 Час читання: 9 хв

AOT (Ahead-Of-Time) — технологогія компіляції, при якій вихідний код або байт-код перетворюється в машинні інструкції до запуску програми, на етапі збірки або встановлення. В Android, AOT-компіляція стала ключовою інновацією середовища виконання ART, яке замінило Dalvik у версії 5.0 Lollipop. Згідно з Google, 2024, AOT-компіляція в ART усуває затримки прогріву та знижує енергоспоживання застосунків на 10–15% порівняно з JIT-підходом.

Головне

  • AOT — Ahead-Of-Time компіляція: перетворення коду в машинний до запуску програми.
  • В Android AOT виконується утилітою dex2oat при встановленні APK або в фоновому режимі.
  • Головна перевага AOT — миттівий запуск застосунків без фази прогріву.
  • Недолік — збільшений час встановлення та додатковий об’єм на диску на 15–30%.
  • Сучасні системи використовують гібридний підхід: JIT для перших запусків, AOT для hot-методів.

Що таке AOT-компіляція?

Ahead-Of-Time (AOT) — це метод компіляції, при якому програма перетворюється в машинний код до її запуску. Термін “Ahead-Of-Time” протиставляється JIT (Just-In-Time): якщо JIT компілює “щойно вчасно,” то AOT компілює “заздалегідь.” Компілятор AOT отримує на вхід вихідний код або проміжне представлення (байт-код) і генерує виконуваний файл, готовий до запуску.

Історія AOT сягає традиційних компіляторів C та C++, де компіляція завжди виконується до виконання. У контексті керованих мов (Java, C#, Dart), AOT — більш пізня інновація: довгий час вважалося, що динамічні можливості (рефлексія, динамічне завантаження класів) роблять AOT складно реалізуваним. Google вирішила цю задачу для Android, створивши dex2oat — AOT-компілятор DEX-байт-коду в нативний код.

Принцип роботи AOT

AOT-компілятор виконує повний цикл трансляції. Перший етап — парсинг та побудова абстрактного синтаксичного дерева (AST). Другий — аналіз та оптимізація: видалення мертвого коду, інлайнінг, оптимізація циклів. Третій — генерація машинного коду для цільової архітектури (ARM, ARM64, x86). Результат — виконуваний файл, який не потребує додаткової обробки під час виконання.

bash
# Ручний запуск AOT-компілятора dex2oat
dex2oat --dex-file=classes.dex \
        --oat-file=classes.oat \
        --arch=arm64 \
        --instruction-set-variant=generic

# Перевірка скомпільованого OAT-файлу
oatdump --oat-file=classes.oat --output=oat_dump.txt

AOT в Android: dex2oat та OAT-файли

В Android AOT-компіляція реалізована через утиліту dex2oat (dalvik executable to optimized android translator). Коли користувач встановлює застосунок, система запускає dex2oat, який зчитує DEX-файли з APK, оптимізує байт-код та створює OAT-файл — ELF-бінарник з нативним кодом. Цей файл зберігається в розділі /data/dalvik-cache/.

Процес компіляції включає кілька рівнів оптимізації. Базовий рівень — верифікація байт-коду та базові оптимізації (dead code elimination, constant folding). Середній — інлайнінг методів, loop unrolling, аналіз ескейп-аналізу. Максимальний — глобальні оптимізації всього застосунку, включаючи девіртуалізацію та оптимізацію розміру стеку. Рівень оптимізації залежить від режиму компіляції (speed, speed-profile, space).

Структура OAT-файлу

OAT-файл має формат ELF (Executable and Linkable Format) — той самий, що використовують нативні Linux-бінарники. Всередині OAT-файлу знаходиться скомпільований код для кожного методу застосунку, а також метадані: інформація про класи, поля, методи та зв’язки між ними. ART використовує ці метадані для швидкого завантаження класів та вирішення символічних посилань без повного парсингу DEX.

Компонент OATПризначення
ELF headerЗаголовок формату ELF
Code sectionМашинний код скомпільованих методів
OAT headerМетадані ART: версія, розміри секцій
DEX sectionsВихідні DEX-дані для рефлексії
Link tableТаблиця зв’язків для JNI та нативних бібліотек

AOT vs JIT: порівняльний аналіз

AOT і JIT представляють різні точки в просторі компромісу між продуктивністю та гнучкістю. AOT забезпечує максимальну швидкість виконання з першої секунди, але вимагає більше дискового простору та часу на встановлення. JIT економить місце та час встановлення, але платить за це затримками прогріву та піковим енергоспоживанням.

Ключовий фактор вибору — сценарій використання. Для застосунків, які запускаються один раз і працюють довго (ігри, редактори, навігація), AOT кращий — витрати на компіляцію окупаються стабільною продуктивністю. Для невеликих утиліт, які запускаються рідко і на короткий час, JIT може бути вигіднішим — швидке встановлення та малий об’єм важливіші за пікову продуктивність.

КритерійAOTJIT
ЗапускМиттівийЗ прогрівом
ВстановленняДовше (компіляція)Швидко
Дисковий простір+15–30%Мінімально
ЕнергоспоживанняСтабільнеПіки при компіляції
АдаптивністьНизькаВисока

Продуктивність коду

Цікавий нюанс: AOT-код не завжди швидший за JIT. JIT має доступ до профільної інформації часу виконання — точних типів об’єктів, частоти викликів, реальних патернів гілок. Це дозволяє застосовувати оптимізації, недоступні AOT (наприклад, профільно-керований інлайнінг). На практиці різниця в продуктивності скомпільованого коду між AOT та JIT становить ±5–10% залежно від сценарію.

Переваги AOT-компіляції

AOT надає три ключові переваги для мобільних застосунків. Перша — предбачувана продуктивність. Користувач не бачить “заїкань” в перші секунди: застосунок працює з максимальною швидкістю з першого кадру. Це критично важливо для ігор, анімацій та інтерфейсів з плавними переходами.

Друга — енергоефективність. AOT не створює пікових навантажень на CPU, характерних для JIT-компіляції. Процесор працює в стабільному режимі, що знижує енергоспоживання на 10–15% в період перших 30–60 секунд роботи застосунку. Для типового користувача, який запускає 20–30 застосунків на день, це дає помітний приріст часу автономної роботи.

Спрощення runtime

AOT-компіляція спрощує середовище виконання. Коли весь код вже скомпільовано, відпадає необхідність в JIT-компіляторі, інтерпретаторі та профілювальнику в runtime. Це зменшує розмір самого середовища виконання та знижує ймовірність помилок. ART в режимі повної AOT займає приблизно на 15% менше оперативної пам’яті, ніж аналогічне середовище з активним JIT.

Недоліки AOT-компіляції

Головний недолік AOT — час встановлення. На ранніх пристроях з Android 5.0 встановлення великих застосунків (100–200 МБ) могло займати 2–5 хвилин через AOT-компіляцію. Це створювало негативний користувацький досвід: після завантаження APK доводилося чекати, перніж відкрити застосунок. Google частково вирішила цю проблему в Android 7.0, перейшовши на гібридну схему.

Другий недолік — займаєме місце. OAT-файли на 15–30% більші за вихідні DEX-файли. На пристроях з 8–16 ГБ вбудованої пам’яті кожен застосунок “з’їдає” додаткове місце на системному розділі. Для користувачів з великою кількістю встановлених застосунків (50–100) це може призвести до нестачі місця для системних оновлень.

Відсутність адаптивності

AOT-код фіксується на момент компіляції. Якщо застосунок використовує різні патерни виконання залежно від версії Android, моделі пристрою або налаштувань користувача, AOT не може адаптуватися. Оптимізації, вибрані для одного сценарію, можуть бути неоптимальними для іншого. JIT в цьому плані більш гнучкий: він перекомпілює hot-методи при зміні умов виконання.

AOT за межами Android: Flutter, .NET, Go

AOT-компіляція застосовується не тільки в Android. Flutter використовує AOT для компіляції Dart-коду в нативний код для iOS та Android. Це забезпечує продуктивність UI на рівні 60 fps навіть на слабких пристроях. На етапі розробки Flutter використовує JIT (hot reload), а для релізної збірки — AOT, об’єднуючи переваги обох підходів.

В екосистемі .NET технологія ReadyToRun (R2R) дозволяє компілювати збірки в нативний код заздалегідь. Це скорочує час запуску .NET-застосунків на 30–50%. Компілятор Go споконвіку є AOT-компілятором: програми на Go компілюються в один статичний бінарник без зовнішніх залежностей, що робить їх ідеальними для контейнерного середовища.

dart
// Flutter: AOT-компіляція Dart в нативний код
// Релізна збірка використовує AOT
flutter build apk --release

// Результат: libapp.so з AOT-скомпільованим Dart-кодом
// Розробка використовує JIT (hot reload)
flutter run

AOT та безпека

Додаткова перевага AOT — ускладнення зворотної розробки. Скомпільований нативний код важче декомпілювати, ніж байт-код. Інструменти на кшталт JADX та APKTool працюють з DEX-форматом, але не можуть відновити вихідний код з OAT-файлів на тому ж рівні деталізації. Це не замінює обфускацію (ProGuard, R8), але створює додатковий бар’єр для аналізаторів.

Гібридна стратегія: профільована компіляція

Сучасний стандарт в Android — профільована AOT-компіляція, реалізована в ART починаючи з Android 7.0. При встановленні застосунок не компілюється повністю — натомість використовується швидка верифікація байт-коду та JIT для перших запусків. Це вирішує проблему довгого встановлення, характерну для чистої AOT в Android 5.0–6.0.

Після 2–3 запусків застосунку профілювальник ART збирає дані про реальне використання та визначає, які методи найкритичніші для продуктивності. Потім в фоновому режимі (звичайно вночі, коли пристрій заряджається) dex2oat компілює ці hot-методи в нативний код. Після фонової компіляції застосунок отримує продуктивність, еквівалентну повній AOT, без негативного впливу на користувацький досвід при встановленні.

kotlin
// Програмне керування режимом компіляції (Android 9+)
fun requestProfileCompilation(context: Context) {
    val pm = context.packageManager
    // Рекомендується використовувати профільовану компіляцію
    pm.setComponentEnabledSetting(
        ComponentName(context, javaClass()),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

Оптимізація під гібридний режим

Для максимальної вигоди від гібридної компіляції розробникам варто дотримуватися кількох правил. Використовуйте базові профілі (baseline profiles) — попередньо зібрані профілі, які постачаються разом з APK і дозволяють ART почати AOT-компіляцію hot-методів одразу після встановлення. Базові профілі скорочують час досягнення повної продуктивності з 2–х запусків до першого ж запуску.

Часто задавані питання

Що таке AOT-компіляція простими словами?

AOT — це переклад програми в машинний код заздалегідь, до того, як користувач її запустить. Уявіть, що книга перекладена на вашу мову ціликом до того, як ви її відкрили — ви читаєте одразу, без затримок на переклад сторінок.

Чим AOT відрізняється від JIT?

AOT компілює код при встановленні (довше встановлення, але швидший запуск). JIT компілює код під час роботи (швидке встановлення, але перші секунди повільніші). Сучасні системи комбінують обидва підходи.

Чому Android перейшов з Dalvik на ART з AOT?

Google хотіла усунути проблему JIT-прогріву — затримок в перші секунди роботи застосунку. AOT-компіляція в ART забезпечила миттівий запуск та знизила енергоспоживання, що було критично важливо для мобільних пристроїв.

Як AOT впливає на розмір застосунку?

Розмір APK не змінюється — AOT-компіляція створює OAT-файли на системному розділі, які на 15–30% більші за вихідні DEX-файли. Користувач бачить це як зменшення вільного місця вбудованої пам’яті, а не як збільшення розміру завантажуваного файлу.

Що таке профільована AOT?

Це гібридний підхід, при якому перші запуски застосунку використовують JIT, а потім система в фоні компілює тільки часто використовувані методи в нативний код. Це поєднує швидке встановлення JIT з високою продуктивністю AOT.

Підсумки

  • AOT (Ahead-Of-Time) — компіляція байт-коду в машинний код до запуску програми, на етапі встановлення.
  • В Android AOT реалізовано через утиліту dex2oat, що створює ELF-бінарники (OAT-файли).
  • Головні переваги AOT: миттівий запуск, стабільна продуктивність та низьке енергоспоживання.
  • Головні недоліки: збільшений час встановлення та додатковий об’єм на диску на 15–30%.
  • AOT застосовується не тільки в Android, ай в Flutter (Dart), .NET (R2R) та Go.
  • Сучасний ART використовує профільовану AOT: JIT для перших запусків, фонова компіляція hot-методів.
  • Baseline profiles дозволяють почати AOT-компіляцію ключових методів одразу після встановлення застосунку.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також