Dalvik: was ist das, virtuelle Maschine und wie funktioniert sie

Autor: IT Sectr Veröffentlicht: 2026-04-16 Lesezeit: 9 Min.

Die virtuelle Maschine Dalvik war eine Schlüsselkomponente des Android-Betriebssystems, die bis zur Version 4.4 KitKat für die Ausführung von Anwendungen verantwortlich war. Entwickelt von Dan Bornstein, ersetzte diese registerbasierte VM das Konzept der Standard-JVM und ermöglichte die Optimierung des Anwendungsstarts auf mobilen Geräten mit begrenztem RAM. Laut Google, 2024, gewährleistete Dalvik die Anwendungskompatibilität durch JIT-Kompilierung, indem es DEX-Bytecode direkt während der Ausführung in Maschinenbefehle umwandelte.

Wichtige Punkte

  • Dalvik ist eine virtuelle Maschine mit registerbasierter Architektur, optimiert für Android.
  • Im Gegensatz zur JVM führt Dalvik DEX-Bytecode aus, der speziell für mobile Geräte komprimiert ist.
  • Die JIT-Kompilierung wandelt einen Teil des DEX-Codes direkt während der Ausführung der Anwendung in Maschinencode um.
  • Ab Android 5.0 wurde Dalvik durch ART mit vorausschauender AOT-Kompilierung ersetzt.
  • Das Verständnis von Dalvik ist für die Unterstützung älterer Android-Versionen und die Analyse der Abwärtskompatibilität erforderlich.

Was ist Dalvik?

Dalvik ist eine virtuelle Maschine mit registerbasierter Architektur, die speziell für die Android-Plattform entwickelt wurde. Die Entwicklung begann 2005 durch die Firma von Dan Bornstein, und 2007 wurde das Projekt von Google übernommen. Die erste kommerzielle Version von Dalvik erschien mit der Veröffentlichung von Android 1.0 im Jahr 2008.

Im Gegensatz zur standardmäßigen Java Virtual Machine (JVM) führt Dalvik keinen Java-Bytecode aus. Der Java-Compiler wandelt Quellcode in Class-Dateien um, und dann übersetzt das Dienstprogramm dx diese in das Dalvik Executable (DEX)-Format. Dieses Format ist kompakter als Class-Dateien: Eine 10 MB große Anwendung im Class-Format nimmt in DEX etwa 6–7 MB ein.

Entstehungsgeschichte

Dan Bornstein schrieb Dalvik als Projekt für Betriebssysteme mit begrenzten Ressourcen. Der Name stammt vom isländischen Dorf Dalvík. Google wählte Dalvik statt JVM aufgrund von Lizenzbeschränkungen und der Notwendigkeit einer tiefgreifenden Optimierung für mobile Prozessoren mit ARM-Architektur. Das System gewann schnell an Popularität: Bis 2012 liefen mehr als 500 Millionen Android-Geräte mit Dalvik.

Rolle im Android-Ökosystem

Jede Android-Anwendung wird in einem separaten Prozess mit einer eigenen Instanz der Dalvik VM ausgeführt. Dies gewährleistet Datenisolierung und Schutz vor schädlichem Code auf Betriebssystemebene. Dieser Ansatz kombiniert die Vorteile der Virtualisierung mit der Linux-Sandbox — Malware in einer Anwendung kann benachbarte Prozesse nicht beeinflussen.

Dalvik-Architektur: Registermaschine und DEX

Die registerbasierte Architektur von Dalvik unterscheidet sich grundlegend von der stackbasierten Architektur der JVM. Anstatt Operationen auf dem Stack-Stack auszuführen, arbeitet Dalvik mit Registern — virtuellen Zellen innerhalb der VM. Jeder Befehl enthält die Adressen der Operandenregister, was die Anzahl der Befehle pro Operation reduziert.

Die JVM-Stack-Maschine verwendet Befehle wie push, pop und add — zum Addieren zweier Zahlen sind drei Befehle erforderlich. Dalvik löst dieselbe Aufgabe mit einem add-int-Befehl mit drei Registern. Laut Android Open Source Project reduziert die registerbasierte DEX-Architektur die Bytecode-Größe im Durchschnitt um 30% im Vergleich zum stackbasierten Class-Format.

DEX-Format

Eine DEX-Datei (Dalvik Executable) enthält eine komprimierte Darstellung aller Klassen der Anwendung. Der Dateiheader enthält eine Prüfsumme, Abschnittsgrößen und Offsets. Die Hauptabschnitte sind Pools für Zeichenketten, Typen, Methodenprototypen, Felder und den Bytecode selbst. Eine einzelne DEX-Datei kann bis zu 65.536 Methoden speichern (die Beschränkung wurde mit der Einführung von Multi-Dex in Android 5.0 aufgehoben).

Das dx-Dienstprogramm, das in den Android SDK Build Tools enthalten ist, wird verwendet, um Class-Dateien in DEX zu konvertieren. Beispielbefehl: dx --dex --output=classes.dex myapp.jar. Moderne Projekte verwenden D8, den Nachfolger von dx mit verbesserter Optimierung und Unterstützung für Java 8+-Funktionen.

bash
# Konvertierung von JAR in DEX mit dx
dx --dex --output=classes.dex myapp.jar

# Moderne Version über D8
d8 --lib android.jar --output dex/ myapp.jar

Zygote: Framework-Vorladen

Der Zygote-Prozess ist ein entscheidendes Element der Dalvik-Architektur. Wenn das System startet, lädt Zygote alle Android-SDK-Klassen, öffnet gemeinsame Bibliotheken und erstellt einen Pool vorab geladener Ressourcen. Wenn ein Benutzer eine Anwendung öffnet, fork-t das System den Zygote-Prozess und erstellt eine neue Dalvik-VM-Instanz mit einem bereits initialisierten Framework. Dies reduziert die Anwendungsstartzeit von ~2–3 Sekunden auf 300–500 Millisekunden.

JIT-Kompilierung in Dalvik

JIT (Just-In-Time) ist eine Technologie zum Kompilieren von Bytecode in Maschinenbefehle direkt während der Ausführung der Anwendung. In Dalvik analysiert der JIT-Compiler den ausgeführten DEX-Code, identifiziert häufig verwendete (heiße) Methoden und kompiliert sie in nativen Code für die CPU.

Die Wahl von JIT anstelle der vollständigen Ahead-Of-Time (AOT)-Kompilierung in frühen Android-Versionen war bewusst getroffen. Mobile Geräte hatten begrenzten Flash-Speicher (4–16 GB) — das Vorabkompilieren aller Anwendungen hätte erheblichen Platz beansprucht. Darüber hinaus war der ROM-Speicher in frühen Geräten langsamer als RAM, und das Lesen von vorab kompiliertem Code hätte die Leistung beeinträchtigen können.

JIT-Kompilierungsprozess

Wenn eine Anwendung gestartet wird, beginnt Dalvik mit der Interpretation von DEX-Bytecode. Ein spezieller Profiler verfolgt, welche Methoden am häufigsten aufgerufen werden. Nach Überschreiten einer Schwelle (typischerweise ~200 Aufrufe) wandelt der JIT-Compiler die Methode in Maschinencode um und speichert sie im RAM zwischen. Nachfolgende Aufrufe verwenden die bereits kompilierte Version ohne erneute Kompilierung.

java
// Beispiel einer heißen Methode, die JIT kompilieren wird
public class Calculator {
    public int sumArray(int[] arr) {
        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }
}

JIT-Leistung

Laut Google I/O 2013 beschleunigte die Einführung von JIT in Android 2.2 Froyo die Ausführung von Anwendungen im Durchschnitt um das 2–5-fache im Vergleich zur reinen Interpretation. JIT fügt jedoch beim ersten Start eine Verzögerung hinzu: Eine Anwendung benötigt 3 bis 10 Sekunden zum Aufwärmen und Kompilieren heißer Methoden. Nach dem Aufwärmen stabilisiert sich die Leistung auf einem Niveau nahe dem nativen Code.

Dalvik vs JVM: Hauptunterschiede

Dalvik unterscheidet sich in mehreren grundlegenden Aspekten von der JVM. Erstens — Architektur: JVM ist stackbasiert, Dalvik ist registerbasiert. Zweitens — Bytecode-Format: JVM verwendet Class-Dateien, Dalvik verwendet DEX. Drittens — Speicherverwaltung: Dalvik ist für den begrenzten RAM mobiler Geräte optimiert.

Beide Ansätze haben ihre Stärken. Die stackbasierte JVM benötigt weniger Speicherplatz für die Speicherung von Befehlen — jeder Befehl ist kürzer, da Operanden implizit vom Stack genommen werden. Das registerbasierte Dalvik führt weniger Befehle pro Operation aus, was CPU-Zeit spart und den Stromverbrauch senkt. Für batteriebetriebene mobile Geräte ist dies entscheidend.

ParameterDalvikJVM
ArchitekturRegisterbasiertStackbasiert
BytecodeDEXclass
KompilierungJIT (Android 2.2+)JIT / AOT
OptimierungNiedriger StromverbrauchHohe Kompatibilität
IsolierungÜber Linux-ProzesseÜber ClassLoader

Lizenzaspekte

Die Wahl von Dalvik anstelle von JVM war auch durch Lizenzierung bedingt. Oracle besitzt die Rechte an Java SE und der JVM, und Google wollte Lizenzgebühren vermeiden. Die Erstellung einer eigenen VM mit einem alternativen Bytecode-Format ermöglichte es Android, sich unabhängig von Oracle zu entwickeln. Dieser Streit entwickelte sich zu einem jahrelangen Rechtsstreit, Oracle vs. Google (2010–2021), der zugunsten von Google endete.

DEX-Format und das dx-Dienstprogramm

DEX (Dalvik Executable) ist ein Binärformat, das den kompilierten Code einer Android-Anwendung enthält. Jede DEX-Datei beginnt mit einem Header, gefolgt von Abschnitten: Zeichenkettenkonstanten (string_ids), Typen (type_ids), Methodenprototypen (proto_ids), Felder (field_ids), Methoden (method_ids), Klassendefinitionen (class_defs) und einem Datenbereich.

Das dx-Dienstprogramm konvertiert Java-Class-Dateien in eine oder mehrere DEX-Dateien. Der Algorithmus beinhaltet die Deduplizierung von Konstanten — identische Zeichenketten oder Typen werden einmal gespeichert und per Index referenziert. Dies reduziert die endgültige Größe erheblich. In modernen Projekten wurde dx durch D8 (eingeführt in Android Studio 3.1) ersetzt, das 2–3 mal schneller ist und Java 8-Desugaring unterstützt.

java
// Beispiel für dekompilierten DEX-Bytecode über dexdump
// Quellcode: return a + b;
@Ldalvik/annotation/Code;
    registers: 3
    add-int v0, v1, v2
    return v0

Multi-Dex: Überwindung des 65536-Limits

Die Beschränkung des DEX-Formats auf 65.536 Methoden (16-Bit-Index-Limit) wurde zu einem ernsthaften Problem für große Anwendungen. Die Lösung kam mit Android 5.0: Multi-Dex-Unterstützung erlaubt einer Anwendung, mehrere DEX-Dateien zu enthalten. Die Hauptdatei classes.dex enthält Einstiegspunkte, während zusätzliche Dateien classes2.dex, classes3.dex usw. den restlichen Code enthalten. Die Multi-Dex-Konfiguration wird in build.gradle mit der Zeile multiDexEnabled true aktiviert.

Speicherverwaltung und Garbage Collection

Die Garbage Collection in Dalvik ist als generationaler Collector mit Mark-and-Sweep implementiert. Der Speicher ist in zwei Hauptbereiche unterteilt: Heap (Halde) für Objekte und Stack für Primitive und Referenzen. Wenn der Heap voll wird, suspendiert Dalvik alle Threads (STW — Stop-The-World), markiert erreichbare Objekte und gibt unerreichbare frei.

Vor Android 2.2 verwendete Dalvik einen Single-Thread-Collector mit Pausendauern von bis zu 100–200 ms. Android 2.3 Gingerbread führte einen Concurrent-Collector ein, der typische Pausen auf 5–10 ms reduzierte. Und Android 4.0 Ice Cream Sandwich fügte einen Collector mit inkrementeller Bereinigung hinzu — Concurrent Mark and Sweep (CMS).

Speicherlecks

Ein typisches Problem von Dalvik-Anwendungen sind Speicherlecks durch statische Referenzen auf Activity. Wenn ein statisches Feld eine Referenz auf Context oder View hält, kann der Garbage Collector die Activity auch nach dem Schließen des Bildschirms nicht freigeben. Tools wie Eclipse MAT und LeakCanary helfen, solche Lecks zu erkennen: Sie analysieren einen Heap-Dump und zeigen Referenzketten, die das Objekt halten.

java
// Beispiel für ein Speicherleck durch eine statische Referenz
public class Utils {
    private static Context context;

    public static void init(Context ctx) {
        context = ctx; // Hält Activity nach finish()
    }
}

Einschränkungen von Dalvik und der Übergang zu ART

Trotz ihres Erfolgs hatte Dalvik mehrere Nachteile. Die JIT-Kompilierung erforderte Aufwärmzeit — die ersten Sekunden des Anwendungsbetriebs waren langsamer. Darüber hinaus verbrauchte JIT während der Kompilierung CPU-Leistung, was die Akkulaufzeit verkürzte. Mit zunehmender Leistung mobiler Geräte und wachsendem integriertem Speicher nahm die Notwendigkeit von JIT ab.

In Android 4.4 KitKat führte Google ART (Android Runtime) als experimentellen Ersatz für Dalvik ein. Ab Android 5.0 Lollipop wurde ART zur alleinigen Laufzeitumgebung. Der Hauptunterschied ist die AOT-Kompilierung: Anstatt während der Ausführung zu kompilieren, werden alle Anwendungen während der Installation in Maschinencode kompiliert. Dies beseitigte Aufwärmverzögerungen und verbesserte die Energieeffizienz.

Abwärtskompatibilität

Der Übergang von Dalvik zu ART war für Entwickler transparent: Beide Laufzeiten führen denselben DEX-Bytecode aus. Für Dalvik kompilierte Anwendungen laufen auf ART ohne Neukompilierung — system_server kompiliert sie während der Installation in nativen Code. Eine Ausnahme bildet Code, der Reflektion verwendet, um auf interne Member der Dalvik VM zuzugreifen: Solcher Code könnte auf ART aufgrund von Änderungen der internen Architektur brechen.

Häufig gestellte Fragen

Was ist Dalvik in einfachen Worten?

Dalvik ist ein Vermittlerprogramm, das Android-Anwendungen auf dem Telefon ausführt. Es nimmt den Anwendungscode und wandelt ihn in für den Prozessor verständliche Befehle um, und zwar direkt während der Arbeit des Benutzers.

Wie unterscheidet sich Dalvik von der JVM?

Dalvik verwendet eine registerbasierte Architektur und das DEX-Format, während die JVM eine stackbasierte Architektur und das Class-Format verwendet. Dalvik ist für mobile Geräte mit begrenztem Speicher und Prozessorleistung optimiert, während die JVM für Desktop-Computer und Server ausgelegt ist.

Warum hat Google Dalvik durch ART ersetzt?

ART bietet eine höhere Leistung durch vorausschauende AOT-Kompilierung — die Anwendung wird einmal während der Installation kompiliert, nicht jedes Mal beim Start. Dies beschleunigt den Betrieb und spart im Vergleich zum JIT-Ansatz von Dalvik Batterie.

Funktionieren alte Anwendungen unter ART?

Ja, ART ist vollständig abwärtskompatibel mit Dalvik-DEX-Bytecode. Während der Installation kompiliert ART alte DEX-Dateien in nativen Code. Eine Ausnahme bilden Anwendungen, die Reflektion verwenden, um auf interne Dalvik-Mechanismen zuzugreifen.

Was ist eine DEX-Datei?

DEX (Dalvik Executable) ist ein ausführbares Dateiformat, das komprimierten Bytecode einer Android-Anwendung enthält. Eine einzelne APK kann mehrere DEX-Dateien (Multi-Dex) enthalten, wenn die Anwendung mehr als 65.536 Methoden hat.

Zusammenfassung

  • Dalvik VM ist eine registerbasierte virtuelle Maschine, die für Android entwickelt und bis Version 4.4 KitKat verwendet wurde.
  • Das DEX-Format bietet kompakte Bytecode-Speicherung — 30% kleiner als JVM-Class-Dateien.
  • Die JIT-Kompilierung in Dalvik beschleunigte die Anwendungsausführung um das 2–5-fache im Vergleich zur reinen Interpretation.
  • Der Zygote-Prozess lädt das Android-Framework vor und reduziert die Anwendungsstartzeit auf 300–500 ms.
  • Die Beschränkung auf 65.536 Methoden in einer einzelnen DEX-Datei wird ab Android 5.0 durch Multi-Dex gelöst.
  • Die Garbage Collection in Dalvik entwickelte sich vom Single-Thread-STW zum Concurrent Mark and Sweep.
  • Der Übergang zu ART in Android 5.0 beseitigte JIT-Aufwärmverzögerungen und verbesserte die Energieeffizienz.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch