DEX: шта је то, структура и принцип рада бајт-кода

Аутор: IT Sectr Објављено: 2026-04-15 Време читања: 8 мин

DEX (Dalvik Executable) је формат бајт-кода у који се компилира изворни код Android апликација на Java и Kotlin-у. DEX датотеке извршава виртуелна машина Dalvik (до Android 4.4) или Android Runtime (ART, од Android 5.0). Према подацима Android Open Source Project, 2026, формат DEX у просеку обезбеђује 30% компактније представљање кода у поређењу са стандардним JVM бајт-кодом.

Главне тачке

  • DEX — формат бајт-кода за Android, који се извршава на Dalvik или ART.
  • Компактност — DEX заузима 30% мање простора од стандардног Java бајт-кода.
  • Multidex — механизам за превазилажење лимита од 65536 метода у једној DEX датотеци.
  • ART — Android Runtime, који је заменио Dalvik, компилира DEX у изворни код при инсталацији.
  • D8 — савремени компилатор Java/Kotlin у DEX, који је заменио DX од 2018. године.

Шта је DEX и зашто је потребан

DEX (Dalvik Executable) је формат бајт-кода дизајниран посебно за Android мобилне уређаје. За разлику од стандардног Java бајт-кода (.class датотеке), DEX је оптимизован за ограничене ресурсе: мање меморије, мања величина и брже учитавање класа.

Од Java до DEX-а

Изворни код на Java или Kotlin-у компилира се javac/kotlinc у стандардне .class датотеке (Java бајт-код). Затим алат d8 (или раније dx) конвертује .class у једну или више DEX датотека. Ова конверзија није једноставно препакивање — d8 обавља оптимизације: спаја константне пулове, преписује инструкције у регистарску архитектуру и уклања дуплиране податке.

Архитектонске карактеристике

DEX користи регистарску архитектуру (за разлику од стековне JVM). Свака метода има фиксан број регистара (до 65536). DEX инструкције су краће — у просеку 2 бајта наспрам 1–4 бајта у JVM-у. Ово даје компактнији код: типична апликација се смањује са 10–15 MB .class на 4–6 MB .dex.

Структура DEX датотеке: секције и заглавље

DEX датотека има строго дефинисану бинарну структуру. Свака датотека почиње заглављем и садржи неколико секција које се међусобно позивају преко офсета.

СекцијаНамена
headerЗаглавље: magic, контролна сума, потпис, величине и офсети секција
string_idsТабела ниски: имена класа, метода, поља
type_idsТипови: референце на идентификаторе ниски типова
proto_idsПрототипови метода: повратни тип и параметри
field_idsПоља класа: класа, тип, име
method_idsМетоде: класа, прототип, име
class_defsДефиниције класа: заставице, superclass, интерфејси, офсети података
dataСтварни подаци: код метода, анотације, debug информације

Заглавље DEX-а

Магични број DEX-а — `dex\n035\0` (верзија 035). Друге верзије: 036, 037, 038 (за Android 8.0+). Заглавље величине 0x70 бајтова садржи SHA-1 контролну суму и офсете свих секција. Валидација заглавља — први корак при учитавању DEX-а од стране виртуелне машине.

Константни пулови

string_ids, type_ids, proto_ids, field_ids, method_ids — су индексиране табеле. Уместо чувања пуних имена у коду методе користи се 4-бајтни индекс. Ово је кључна оптимизација: ако се класа помиње 100 пута, њено име се чува једном у string_ids. dex2oat при компилацији ART додатно оптимизује ове табеле.

Процес компилације Java и Kotlin у DEX

Процес претварања изворног кода у DEX састоји се од неколико фаза. Савремени ланац користи компилатор D8, који је заменио DX 2018. године са Android Gradle Plugin 3.2.

Фаза 1: Компилација у .class

javac (за Java) или kotlinc (за Kotlin) компилирају изворни код у .class датотеке. Свака класа — засебна .class датотека у Java бајт-коду. У овој фази се обавља провера типова, генерисање bridge метода и уграђивање константи.

Фаза 2: D8 компилација

D8 прима све .class датотеке и претвара их у DEX бајт-код. D8 обавља неколико оптимизација: уклања некоришћене аргументе метода, спаја константне пулове из различитих .class у један глобални DEX пул, конвертује стековне инструкције JVM у регистарске инструкције Dalvik-а.

kotlin
// Kotlin изворни код
data class User(
    val name: String,
    val email: String
)

fun greet(user: User): String {
    return "Hello, ${user.name}!"
}

Након D8 компилације, овај код се претвара у компактне DEX инструкције: const-string за учитавање ниске, iget-object за приступ пољу објекта, invoke-virtual за позив StringBuilder.append.

D8 против DX

D8 ради 2–3 пута брже од DX-а, генерише компактнији DEX (за 5–10%) и боље оптимизује Kotlin-специфичне конструкције (inline функције, lambda). DX је означен као deprecated од 2018. године и уклоњен из Android Gradle Plugin 8.0.

Dalvik против ART: како се променило извршавање DEX-а

Извршавање DEX кода у Android-у је прошло кроз две фазе: оригинална виртуелна машина Dalvik (Android 2.2–4.4) и Android Runtime ART (Android 5.0+). Разлика у приступу компилацији је кардинална.

Dalvik VM: JIT компилација

Dalvik је користио Just-In-Time (JIT) компилацију: DEX бајт-код је интерпретиран, а често позиване методе су компилиране у изворни код у лету. Предност — брза инсталација. Недостатак — спорије покретање и стално оптерећење процесора за JIT.

ART: AOT компилација

ART (Android Runtime) компилира DEX у изворни код при инсталацији апликације путем dex2oat. Ово је Ahead-Of-Time (AOT) приступ: инсталација траје дуже, али покретање је брже и потрошња енергије мања. Од Android 7.0 ART користи хибридни приступ — AOT + JIT + Profile Guided Optimization.

dex2oat: конверзија при инсталацији

Алат dex2oat покреће се при инсталацији или ажурирању апликације. Он компилира DEX у ELF датотеку са изворним кодом за архитектуру уређаја. Резултат — .oat и .art датотеке у директоријуму /data/dalvik-cache/. Google стално побољшава dex2oat: на Android 14 додата је оптимизација за склопиве уређаје.

Multidex: превазилажење лимита од 64K метода

Ограничење од 65536 метода по једној DEX датотеци — наслеђе из Dalvik архитектуре. Поље method_ids у заглављу DEX-а заузима 4 бајта, што даје максимално 2^16 = 65536 јединствених референци. Модерне апликације са Google Play Services, Firebase и другим SDK-јима лако прелазе овај лимит.

Механизам Multidex

Multidex је механизам поделе кода на више DEX датотека. Главна classes.dex садржи улазне тачке (Application класу, главне Activity), остале — classes2.dex, classes3.dex и тако даље. При покретању, класе из додатних DEX-ова се учитавају преко DexClassLoader-а.

kotlin
// build.gradle.kts — укључивање multidex-а
android {
    defaultConfig {
        multiDexEnabled = true
    }
}

// Application класа са подршком за multidex
class MyApp : Application() {
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

Проблеми са Multidex-ом

Учитавање додатних DEX-ова у фази покретања апликације може изазвати ANR (Application Not Responding) на уређајима са Android-ом до 5.0. Препорука — користити multidex само када је неопходно и минимизирати зависности како се не би прекорачио лимит.

Оптимизација DEX-а: ProGuard, R8 и обфускација

Оптимизација DEX-а — стандардна фаза израде release верзије Android апликације. Алати R8 и ProGuard смањују величину DEX-а, обфускују код и уклањају некоришћене класе.

R8 против ProGuard

R8 — наследник ProGuard-а, уграђен у Android Gradle Plugin од 2019. године. R8 обавља минификацију, обфускацију и оптимизацију у једном пролазу, док је ProGuard захтевао две фазе: ProGuard → D8. ProGuard се и даље подржава, али Google препоручује R8 за нове пројекте.

R8 уклања некоришћене класе, методе и поља, преименује их у кратка имена (a, b, c), уграђује inline функције и одбацује мртав код. Резултат — DEX се смањује за 20–40% без губитка функционалности.

R8 правила

Конфигурација R8 се задаје у датотеци proguard-rules.pro. Програмер може навести које класе не смеју да се преименују (на пример, за рефлексију или Gson серијализацију). Firebase и други SDK-ји испоручују сопствена правила у својим зависностима.

Декомпилација DEX-а: алати и заштита

DEX се може декомпилирати назад у Java код. Ово је кључно питање безбедности Android апликација: без обфускације код се обнавља до нивоа блиског оригиналу.

Алати за декомпилацију

JADX — најпопуларнији декомпилатор DEX-а у Java. Он обнавља имена класа, метода, поља и већину логике. apktool декомпилира DEX у smali код (Dalvik асемблер) — нисконивоску репрезентацију блиску оригиналним инструкцијама. Bytecode Viewer обједињује неколико декомпилатора у једном интерфејсу.

Методе заштите

Обфускација R8/ProGuard — прва линија одбране: имена класа и метода постају нечитљива. DexGuard — комерцијални алат са додатним методама: шифровање ниски, провера интегритета, анти-tamper. Обфускација на нивоу Control Flow (O-LLVM) мења структуру кода, задржавајући његову функционалност, али чинећи анализу много тежом.

Често постављана питања

По чему се DEX разликује од Java бајт-кода?

DEX користи регистарску архитектуру уместо стековне JVM, има компактнији формат (30% мањи), спаја све .class датотеке у једну датотеку са јединственим константним пулом и користи 16-битне индексе уместо 8-битних.

Шта је smali?

Smali — асемблер DEX бајт-кода. Свака DEX инструкција има текстуалну репрезентацију у smali формату. Алат baksmali конвертује DEX у smali (дезасемблирање), а smali саставља smali назад у DEX.

Како проверити број метода у DEX-у?

Gradle task countMethods или прикључак dex-method-counts показују број метода у свакој DEX датотеци. Команда adb shell са dumpsys такође приказује статистику учитаних DEX-ова за инсталиране апликације.

Да ли број DEX датотека утиче на перформансе?

Да, на уређајима са Android-ом до 8.0 вишеструки DEX успорава покретање апликације, јер се свака додатна датотека учитава засебно. На ART-у са Android 8.0+ разлика је минимална захваљујући компилацији dex2oat у јединствену .oat датотеку.

Може ли се DEX покренути без Android-а?

Да, постоје пројекти попут dexplorer и Android-компатибилне JVM имплементације које могу да извршавају DEX бајт-код ван Android-а. Међутим, већина DEX датотека користи Android API, што их чини неподесним за покретање на обичној JVM.

Резиме

  • DEX — Android бајт-код формат са регистарском архитектуром и компактним приказом кода.
  • Структура укључује заглавље, табеле идентификатора и секцију података са инструкцијама.
  • Компилација у DEX обавља се преко D8: .class → DEX са оптимизацијама и спајањем константних пулова.
  • ART компилира DEX у изворни код при инсталацији (AOT), убрзавајући покретање апликације.
  • Multidex — решење проблема лимита од 65536 метода кроз поделу на више DEX датотека.
  • Оптимизација — R8 смањује DEX за 20–40%, обфускује имена и уклања мртав код.
  • Заштита — обфускација R8/ProGuard, DexGuard и O-LLVM спречавају декомпилацију DEX-а.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође