Dalvik: ce este, mașină virtuală și cum funcționează

Autor: IT Sectr Publicat: 2026-04-16 Timp de citire: 9 min

Mașina virtuală Dalvik — o componentă cheie a sistemului de operare Android, responsabilă pentru executarea aplicațiilor până la versiunea 4.4 KitKat. Dezvoltată de Dan Bornstein, mașina virtuală pe registre a înlocuit conceptul JVM standard și a permis optimizarea lansării aplicațiilor pe dispozitive mobile cu memorie RAM limitată. Potrivit Google, 2024, Dalvik asigura compatibilitatea aplicațiilor prin compilare JIT, transformând DEX-bytecodul în instrucțiuni mașină direct în timpul execuției.

Principalele

  • Dalvik — mașină virtuală cu arhitectură pe registre, optimizată pentru Android.
  • Spre deosebire de JVM, Dalvik execută DEX-bytecod, special comprimat pentru dispozitive mobile.
  • Compilarea JIT transformă o parte din codul DEX în cod mașină direct în timpul funcționării aplicației.
  • Începând cu Android 5.0, Dalvik a fost înlocuit cu ART cu compilare prealabilă AOT.
  • Înțelegerea Dalvik este necesară pentru suportul versiunilor vechi de Android și analiza compatibilității inverse.

Ce este Dalvik?

Dalvik — mașină virtuală cu arhitectură pe registre, creată special pentru platforma Android. Dezvoltarea a început în 2005 în compania lui Dan Bornstein, iar în 2007 proiectul a fost achiziționat de Google. Prima versiune comercială Dalvik a apărut odată cu lansarea Android 1.0 în 2008.

Spre deosebire de Mașina Virtuală Java standard (JVM), Dalvik nu execută bytecod Java. Compilatorul Java transformă codul sursă în fișiere class, iar apoi utilitarul dx le traduce în formatul Dalvik Executable (DEX). Acest format este mai compact decât fișierele class: o aplicație de 10 MB în format class ocupă aproximativ 6–7 MB în DEX.

Istoria creării

Dan Bornstein a scris Dalvik ca un proiect pentru sisteme de operare cu resurse limitate. Numele provine de la satul islandez Dalvík. Google a ales Dalvik în locul JVM din cauza restricțiilor de licențiere și a necesității de optimizare profundă pentru procesoare mobile cu arhitectură ARM. Sistemul a câștigat rapid popularitate: până în 2012, peste 500 de milioane de dispozitive Android funcționau pe Dalvik.

Rolul în ecosistemul Android

Fiecare aplicație Android rulează într-un proces separat cu propria instanță Dalvik VM. Acest lucru asigură izolarea datelor și protecția împotriva codului malițios la nivelul sistemului de operare. Această abordare combină avantajele virtualizării cu sandbox-ul Linux — malware-ul dintr-o aplicație nu poate afecta procesele învecinate.

Arhitectura Dalvik: mașină pe registre și DEX

Arhitectura pe registre Dalvik diferă fundamental de arhitectura pe stivă a JVM. În locul operațiilor cu vârful stivei, Dalvik operează cu registre — celule virtuale în interiorul VM. Fiecare instrucțiune conține adresele registrelor operanzilor, ceea ce reduce numărul de instrucțiuni per operație.

Mașina pe stivă JVM folosește instrucțiuni precum push, pop și add — pentru a aduna două numere sunt necesare trei instrucțiuni. Dalvik rezolvă aceeași sarcină cu o singură instrucțiune add-int cu trei registre. Potrivit Android Open Source Project, arhitectura pe registre a DEX reduce volumul bytecodului în medie cu 30% față de formatul pe stivă class.

Formatul DEX

Fișierul DEX (Dalvik Executable) conține reprezentarea comprimată a tuturor claselor aplicației. Antetul fișierului include suma de control, dimensiunile secțiunilor și decalajele. Secțiunile principale sunt pool-urile de șiruri, tipuri, prototipuri de metode, câmpuri și bytecodul propriu-zis. Într-un singur fișier DEX pot fi stocate până la 65536 de metode (limitarea a fost eliminată prin introducerea multi-dex în Android 5.0).

Pentru conversia fișierelor class în DEX se folosește utilitarul dx, parte a Android SDK Build Tools. Exemplu de comandă: dx --dex --output=classes.dex myapp.jar. Proiectele moderne folosesc D8 — succesorul dx cu optimizare îmbunătățită și suport pentru funcții Java 8+.

bash
# Conversia JAR în DEX cu ajutorul dx
dx --dex --output=classes.dex myapp.jar

# Versiunea modernă prin D8
d8 --lib android.jar --output dex/ myapp.jar

Zygote: preîncărcarea framework-ului

Procesul Zygote — cel mai important element al arhitecturii Dalvik. La pornirea sistemului, Zygote încarcă toate clasele Android SDK, deschide bibliotecile comune și creează un pool de resurse preîncărcate. Când utilizatorul deschide o aplicație, sistemul copiază procesul Zygote (fork), creând o nouă instanță Dalvik VM cu framework-ul deja pregătit. Aceasta reduce timpul de lansare a aplicației de la ~2–3 secunde la 300–500 de milisecunde.

Compilarea JIT în Dalvik

JIT (Just-In-Time) — tehnologie de compilare a bytecodului în instrucțiuni mașină direct în timpul executării aplicației. În Dalvik, compilatorul JIT analizează codul DEX executat, identifică metodele frecvent utilizate (hot) și le compilează în cod nativ pentru CPU.

Alegerea JIT în locul compilării complete Ahead-Of-Time (AOT) în versiunile timpurii de Android a fost conștientă. Dispozitivele mobile aveau memorie flash limitată (4–16 GB) — compilarea prealabilă a tuturor aplicațiilor ar fi ocupat spațiu semnificativ. În plus, memoria ROM în dispozitivele timpurii funcționa mai lent decât memoria RAM, iar citirea codului compilat în prealabil ar fi putut reduce performanța.

Procesul de compilare JIT

Când aplicația este lansată, Dalvik începe să interpreteze DEX-bytecodul. Un profiler special monitorizează care metode sunt apelate cel mai frecvent. După depășirea pragului (de obicei ~200 de apeluri), compilatorul JIT transformă metoda în cod mașină și o stochează în memoria RAM. Apelurile ulterioare folosesc versiunea deja compilată fără recompilare.

java
// Exemplu de metodă hot pe care JIT o va compila
public class Calculator {
    public int sumArray(int[] arr) {
        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }
}

Performanța JIT

Potrivit Google I/O 2013, implementarea JIT în Android 2.2 Froyo a accelerat executarea aplicațiilor în medie de 2–5 ori față de interpretarea pură. Cu toate acestea, JIT adaugă o întârziere la prima lansare: aplicația are nevoie de 3 până la 10 secunde pentru încălzire și compilarea metodelor hot. După încălzire, performanța se stabilizează la un nivel apropiat de codul nativ.

Dalvik vs JVM: diferențe cheie

Dalvik diferă de JVM prin câțiva parametri fundamentali. Primul — arhitectura: JVM este pe stivă, Dalvik pe registre. Al doilea — formatul bytecodului: JVM folosește fișiere class, Dalvik — DEX. Al treilea — gestionarea memoriei: Dalvik este optimizat pentru memoria RAM limitată a dispozitivelor mobile.

Ambele abordări au puncte forte. JVM pe stivă necesită mai puțin spațiu pentru stocarea instrucțiunilor — fiecare instrucțiune este mai scurtă, deoarece operanzii sunt luați implicit din stivă. Dalvik pe registre execută mai puține instrucțiuni per operație, ceea ce economisește timpul procesorului și reduce consumul de energie. Pentru dispozitivele mobile alimentate cu baterie, acest lucru este critic.

ParametruDalvikJVM
ArhitecturăPe registrePe stivă
BytecodDEXclass
CompilareJIT (Android 2.2+)JIT / AOT
OptimizareConsum redus de energieCompatibilitate ridicată
IzolarePrin procese LinuxPrin ClassLoader

Aspecte de licențiere

Alegerea Dalvik în locul JVM a fost, de asemenea, determinată de licențiere. Oracle deține drepturile asupra Java SE și JVM, iar Google dorea să evite plățile de licență. Crearea propriei VM cu un format alternativ de bytecod a permis Android să se dezvolte independent de Oracle. Acest conflict a dus la un proces juridic de lungă durată Oracle vs Google (2010–2021), încheiat în favoarea Google.

Formatul DEX și utilitarul dx

DEX (Dalvik Executable) — format binar care conține codul compilat al aplicației Android. Fiecare fișier DEX începe cu un antet (header), urmat de secțiuni: constante șir (string_ids), tipuri (type_ids), prototipuri de metode (proto_ids), câmpuri (field_ids), metode (method_ids), definiții de clase (class_defs) și zona de date (data).

Utilitarul dx transformă fișierele Java class într-unul sau mai multe fișiere DEX. Algoritmul de lucru include deduplicarea constantelor — șirurile sau tipurile identice sunt salvate o singură dată și referite prin index. Aceasta reduce semnificativ dimensiunea finală. În proiectele moderne, dx a fost înlocuit cu D8 (apărut în Android Studio 3.1), care este de 2–3 ori mai rapid și suportă desugaring-ul Java 8.

java
// Exemplu de DEX-bytecod decompilat prin dexdump
// Cod sursă: return a + b;
@Ldalvik/annotation/Code;
    registers: 3
    add-int v0, v1, v2
    return v0

Multi-dex: depășirea limitei de 65536

Limitarea formatului DEX la 65536 de metode (limita indexului de 16 biți) a devenit o problemă serioasă pentru aplicațiile mari. Soluția a apărut în Android 5.0: suportul pentru multi-dex permite aplicației să conțină mai multe fișiere DEX. Fișierul principal classes.dex conține punctele de intrare, iar fișierele suplimentare classes2.dex, classes3.dex și așa mai departe — restul codului. Configurarea multi-dex se activează în build.gradle cu linia multiDexEnabled true.

Gestionarea memoriei și colectarea gunoiului

Colectarea gunoiului în Dalvik este implementată ca un colector generațional (generational) cu marcare și curățare (mark-and-sweep). Memoria este împărțită în două zone principale: Heap (grămadă) pentru obiecte și Stack (stivă) pentru tipuri primitive și referințe. Când Heap se umple, Dalvik suspendă toate firele de execuție (STW — Stop-The-World), marchează obiectele accesibile și eliberează pe cele inaccesibile.

Până la Android 2.2, Dalvik folosea un colector cu un singur fir cu pauze de până la 100–200 ms. În Android 2.3 Gingerbread a apărut un colector concurent, reducând pauzele tipice la 5–10 ms. Iar în Android 4.0 Ice Cream Sandwich a fost adăugat un colector cu curățare incrementală — Concurrent Mark and Sweep (CMS).

Scurgeri de memorie

O problemă tipică a aplicațiilor Dalvik — scurgeri de memorie prin referințe statice la Activity. Dacă un câmp static stochează o referință la Context sau View, colectorul de gunoi nu poate elibera Activity chiar și după închiderea ecranului. Unelte precum Eclipse MAT și LeakCanary ajută la detectarea unor astfel de scurgeri: ele analizează dump-ul Heap și arată lanțurile de referințe care mențin obiectul.

java
// Exemplu de scurgere de memorie prin referință statică
public class Utils {
    private static Context context;

    public static void init(Context ctx) {
        context = ctx; // Menține Activity după finish()
    }
}

Limitările Dalvik și trecerea la ART

În ciuda succesului, Dalvik avea o serie de neajunsuri. Compilarea JIT necesita timp pentru încălzire — primele secunde de funcționare a aplicației erau mai lente. În plus, JIT consuma energie a procesorului în timpul compilării, ceea ce scurta durata de funcționare autonomă. Odată cu creșterea performanței dispozitivelor mobile și a capacității memoriei încorporate, necesitatea JIT a scăzut.

În Android 4.4 KitKat, Google a prezentat ART (Android Runtime) ca înlocuitor experimental pentru Dalvik. Începând cu Android 5.0 Lollipop, ART a devenit singurul mediu de execuție. Diferența principală — compilarea AOT: în locul compilării în timpul execuției, toate aplicațiile sunt compilate în cod mașină la instalare. Aceasta a eliminat întârzierile de încălzire și a îmbunătățit eficiența energetică.

Compatibilitatea inversă

Trecerea de la Dalvik la ART a fost transparentă pentru dezvoltatori: ambele medii execută același DEX-bytecod. Aplicațiile construite pentru Dalvik funcționează pe ART fără recompilare — system_server le compilează în cod nativ la instalare. Excepția o reprezintă codul care folosește reflexia pentru a accesa membrii interni ai Dalvik VM: un astfel de cod s-ar putea să nu funcționeze pe ART din cauza schimbării arhitecturii interne.

Întrebări frecvente

Ce este Dalvik în cuvinte simple?

Dalvik — este un program intermediar care rulează aplicațiile Android pe telefon. Acesta preia codul aplicației și îl transformă în comenzi înțelese de procesor, făcând acest lucru direct în timpul utilizării.

Cu ce diferă Dalvik de JVM?

Dalvik folosește arhitectură pe registre și format DEX, în timp ce JVM folosește arhitectură pe stivă și format class. Dalvik este optimizat pentru dispozitive mobile cu memorie și procesor limitate, în timp ce JVM este destinată computerelor staționare și serverelor.

De ce Google a înlocuit Dalvik cu ART?

ART oferă performanță mai ridicată datorită compilării prealabile AOT — aplicația este compilată o singură dată la instalare, nu de fiecare dată la lansare. Acest lucru accelerează funcționarea și economisește bateria în comparație cu abordarea JIT a Dalvik.

Funcționează aplicațiile vechi pe ART?

Da, ART este complet compatibil invers cu DEX-bytecodul Dalvik. La instalare, ART compilează fișierele DEX vechi în cod nativ. Excepția o reprezintă aplicațiile care folosesc reflexia pentru a accesa mecanismele interne ale Dalvik.

Ce este un fișier DEX?

DEX (Dalvik Executable) — format de fișier executabil care conține bytecodul comprimat al unei aplicații Android. Într-un APK pot exista mai multe fișiere DEX (multi-dex), dacă aplicația conține mai mult de 65536 de metode.

Rezumat

  • Dalvik VM — mașină virtuală pe registre creată pentru Android și utilizată până la versiunea 4.4 KitKat.
  • Formatul DEX asigură stocarea compactă a bytecodului — cu 30% mai puțin decât fișierele class JVM.
  • Compilarea JIT în Dalvik accelera executarea aplicațiilor de 2–5 ori față de interpretarea pură.
  • Procesul Zygote preîncarcă framework-ul Android, reducând lansarea aplicațiilor la 300–500 ms.
  • Limitarea 65536 de metode într-un singur fișier DEX se rezolvă prin multi-dex începând cu Android 5.0.
  • Colectarea gunoiului în Dalvik a evoluat de la STW cu un singur fir la Concurrent Mark and Sweep.
  • Trecerea la ART în Android 5.0 a eliminat întârzierile de încălzire JIT și a îmbunătățit eficiența energetică.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și