DEX: Was es ist, Struktur und Funktionsweise des Bytecode

Autor: IT Sectr Veröffentlicht: 2026-04-15 Lesezeit: 8 Min.

DEX (Dalvik Executable) ist ein Bytecode-Format, in das der Quellcode von Android-Anwendungen in Java und Kotlin kompiliert wird. DEX-Dateien werden von der virtuellen Dalvik-Maschine (bis Android 4.4) oder der Android Runtime (ART, ab Android 5.0) ausgeführt. Laut Android Open Source Project, 2026 bietet das DEX-Format im Durchschnitt eine um 30% kompaktere Codedarstellung im Vergleich zum standardmäßigen JVM-Java-Bytecode.

Wichtige Punkte

  • DEX ist ein Bytecode-Format für Android, das auf Dalvik oder ART ausgeführt wird.
  • Kompaktheit — DEX benötigt 30% weniger Speicherplatz als standardmäßiger Java-Bytecode.
  • Multidex — ein Mechanismus zur Umgehung des Limits von 65536 Methoden in einer einzelnen DEX-Datei.
  • ART — Android Runtime, die Dalvik ersetzt hat, kompiliert DEX bei der Installation in nativen Code.
  • D8 — ein moderner Compiler von Java/Kotlin nach DEX, der DX seit 2018 ersetzt hat.

Was ist DEX und warum wird es benötigt

DEX (Dalvik Executable) ist ein Bytecode-Format, das speziell für Android-Mobilgeräte entwickelt wurde. Im Gegensatz zum standardmäßigen Java-Bytecode (.class-Dateien) ist DEX für begrenzte Ressourcen optimiert: weniger Speicher, kleinere Größe und schnelleres Klassenladen.

Von Java zu DEX

Quellcode in Java oder Kotlin wird von javac/kotlinc in standardmäßige .class-Dateien (Java-Bytecode) kompiliert. Anschließend konvertiert das Werkzeug d8 (oder früher dx) .class in eine oder mehrere DEX-Dateien. Diese Konvertierung ist keine einfache Neuverpackung — d8 führt Optimierungen durch: Zusammenführen von Konstantenpools, Umschreiben von Anweisungen in eine Registerarchitektur und Entfernen doppelter Daten.

Architektonische Merkmale

DEX verwendet eine registerbasierte Architektur (im Gegensatz zur stapelbasierten JVM). Jede Methode hat eine feste Anzahl von Registern (bis zu 65536). DEX-Anweisungen sind kürzer — durchschnittlich 2 Bytes gegenüber 1–4 Bytes in der JVM. Dies führt zu kompakterem Code: Eine typische Anwendung schrumpft von 10–15 MB .class auf 4–6 MB .dex.

Struktur der DEX-Datei: Abschnitte und Header

Eine DEX-Datei hat eine streng definierte binäre Struktur. Jede Datei beginnt mit einem Header und enthält mehrere Abschnitte, die über Offsets aufeinander verweisen.

AbschnittZweck
headerHeader: Magic, Prüfsumme, Signatur, Abschnittsgrößen und Offsets
string_idsZeichenkettentabelle: Klassen-, Methoden- und Feldnamen
type_idsTypen: Verweise auf Typ-String-Identifikatoren
proto_idsMethodenprototypen: Rückgabetyp und Parameter
field_idsKlassenfelder: Klasse, Typ, Name
method_idsMethoden: Klasse, Prototyp, Name
class_defsKlassendefinitionen: Flags, Superklasse, Schnittstellen, Daten-Offsets
dataTatsächliche Daten: Methodencode, Annotationen, Debug-Informationen

DEX-Header

Die magische Zahl von DEX ist `dex\n035\0` (Version 035). Andere Versionen: 036, 037, 038 (für Android 8.0+). Der Header ist 0x70 Bytes groß und enthält eine SHA-1-Prüfsumme und Offsets aller Abschnitte. Die Header-Validierung ist der erste Schritt beim Laden einer DEX durch die virtuelle Maschine.

Konstantenpools

string_ids, type_ids, proto_ids, field_ids, method_ids — dies sind indizierte Tabellen. Anstatt vollständige Namen im Methodencode zu speichern, wird ein 4-Byte-Index verwendet. Dies ist eine entscheidende Optimierung: Wenn eine Klasse 100 Mal referenziert wird, wird ihr Name einmal in string_ids gespeichert. dex2oat optimiert diese Tabellen während der ART-Kompilierung weiter.

Kompilierungsprozess von Java und Kotlin in DEX

Der Prozess der Umwandlung von Quellcode in DEX besteht aus mehreren Phasen. Die moderne Toolchain verwendet den D8-Compiler, der DX im Jahr 2018 mit Android Gradle Plugin 3.2 ablöste.

Phase 1: Kompilierung in .class

javac (für Java) oder kotlinc (für Kotlin) kompilieren den Quellcode in .class-Dateien. Jede Klasse ist eine separate .class-Datei in Java-Bytecode. In dieser Phase werden Typprüfung, Generierung von Bridge-Methoden und Inlining von Konstanten durchgeführt.

Phase 2: D8-Kompilierung

D8 nimmt alle .class-Dateien und wandelt sie in DEX-Bytecode um. D8 führt mehrere Optimierungen durch: Entfernen ungenutzter Methodenargumente, Zusammenführen von Konstantenpools aus verschiedenen .class-Dateien in einen globalen DEX-Pool und Konvertieren von JVM-Stapelanweisungen in Dalvik-Registeranweisungen.

kotlin
// Kotlin-Quellcode
data class User(
    val name: String,
    val email: String
)

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

Nach der D8-Kompilierung wird dieser Code in kompakte DEX-Anweisungen umgewandelt: const-string zum Laden von Zeichenketten, iget-object für den Zugriff auf Objektfelder, invoke-virtual zum Aufrufen von StringBuilder.append.

D8 vs DX

D8 ist 2–3 Mal schneller als DX, erzeugt kompakteres DEX (5–10% kleiner) und optimiert Kotlin-spezifische Konstrukte (Inline-Funktionen, Lambdas) besser. DX wurde 2018 für veraltet erklärt und aus Android Gradle Plugin 8.0 entfernt.

Dalvik vs ART: Wie sich die DEX-Ausführung verändert hat

Die Ausführung von DEX-Code in Android durchlief zwei Phasen: die ursprüngliche virtuelle Dalvik-Maschine (Android 2.2–4.4) und die Android Runtime ART (Android 5.0+). Der Unterschied im Kompilierungsansatz ist grundlegend.

Dalvik VM: JIT-Kompilierung

Dalvik verwendete Just-In-Time (JIT)-Kompilierung: DEX-Bytecode wurde interpretiert und häufig aufgerufene Methoden spontan in nativen Code kompiliert. Vorteil — schnelle Installation. Nachteil — langsamere Startzeit und ständige CPU-Belastung durch JIT.

ART: AOT-Kompilierung

ART (Android Runtime) kompiliert DEX während der Installation der Anwendung über dex2oat in nativen Code. Dies ist ein Ahead-Of-Time (AOT)-Ansatz: Die Installation dauert länger, aber der Start ist schneller und der Stromverbrauch geringer. Seit Android 7.0 verwendet ART einen hybriden Ansatz — AOT + JIT + profilgesteuerte Optimierung.

dex2oat: Konvertierung bei der Installation

Das Werkzeug dex2oat wird beim Installieren oder Aktualisieren einer Anwendung ausgeführt. Es kompiliert DEX in eine ELF-Datei mit nativem Code für die Gerätearchitektur. Das Ergebnis — .oat- und .art-Dateien im Verzeichnis /data/dalvik-cache/. Google verbessert dex2oat kontinuierlich: In Android 14 wurden Optimierungen für faltbare Geräte hinzugefügt.

Multidex: Überwindung des 64K-Methodenlimits

Das Limit von 65536 Methoden pro DEX-Datei ist ein Erbe der Dalvik-Architektur. Das Feld method_ids im DEX-Header belegt 4 Bytes und ergibt maximal 2^16 = 65536 eindeutige Referenzen. Moderne Anwendungen mit Google Play Services, Firebase und anderen SDKs überschreiten dieses Limit leicht.

Multidex-Mechanismus

Multidex ist ein Mechanismus zur Aufteilung von Code auf mehrere DEX-Dateien. Die Hauptdatei classes.dex enthält die Einstiegspunkte (Application-Klasse, Haupt-Activity), die restlichen sind classes2.dex, classes3.dex usw. Beim Start werden Klassen aus zusätzlichen DEX-Dateien über DexClassLoader geladen.

kotlin
// build.gradle.kts — Aktivierung von Multidex
android {
    defaultConfig {
        multiDexEnabled = true
    }
}

// Application-Klasse mit Multidex-Unterstützung
class MyApp : Application() {
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

Probleme mit Multidex

Das Laden zusätzlicher DEX-Dateien beim Start der Anwendung kann auf Geräten mit Android vor 5.0 zu ANR (Application Not Responding) führen. Empfehlung — Multidex nur bei Bedarf verwenden und Abhängigkeiten minimieren, um das Limit nicht zu überschreiten.

DEX-Optimierung: ProGuard, R8 und Verschleierung

Die Optimierung von DEX ist ein Standardschritt beim Erstellen einer Android-Release-Anwendung. Die Werkzeuge R8 und ProGuard reduzieren die DEX-Größe, verschleiern Code und entfernen ungenutzte Klassen.

R8 vs ProGuard

R8 ist der Nachfolger von ProGuard, der seit 2019 in Android Gradle Plugin integriert ist. R8 führt Minimierung, Verschleierung und Optimierung in einem einzigen Durchlauf durch, während ProGuard zwei Phasen benötigte: ProGuard → D8. ProGuard wird weiterhin unterstützt, aber Google empfiehlt R8 für neue Projekte.

R8 entfernt ungenutzte Klassen, Methoden und Felder, benennt sie in kurze Namen um (a, b, c), bindet Inline-Funktionen ein und entfernt toten Code. Das Ergebnis — DEX wird um 20–40% reduziert, ohne Funktionalität zu verlieren.

R8-Regeln

Die R8-Konfiguration wird in der Datei proguard-rules.pro festgelegt. Der Entwickler kann angeben, welche Klassen nicht umbenannt werden dürfen (z. B. für Reflexion oder Gson-Serialisierung). Firebase und andere SDKs liefern eigene Regeln in ihren Abhängigkeiten.

DEX-Dekompilierung: Werkzeuge und Schutz

DEX kann zurück in Java-Code dekompiliert werden. Dies ist eine wichtige Sicherheitsfrage für Android-Anwendungen: Ohne Verschleierung wird Code auf ein dem Original nahes Niveau wiederhergestellt.

Dekompilierungswerkzeuge

JADX ist der beliebteste DEX-zu-Java-Dekompiler. Er stellt Klassennamen, Methoden, Felder und den Großteil der Logik wieder her. apktool dekompiliert DEX in Smali-Code (Dalvik-Assembler) — eine niedrige Darstellung nahe den ursprünglichen Anweisungen. Bytecode Viewer vereint mehrere Dekompilierer in einer Oberfläche.

Schutzmethoden

Die Verschleierung mit R8/ProGuard ist die erste Verteidigungslinie: Klassen- und Methodennamen werden unlesbar. DexGuard ist ein kommerzielles Werkzeug mit zusätzlichen Methoden: Zeichenkettenverschlüsselung, Integritätsprüfung, Anti-Manipulation. Die Kontrollflussverschleierung (O-LLVM) ändert die Codestruktur unter Beibehaltung der Funktionalität und erschwert die Analyse erheblich.

Häufig gestellte Fragen

Wie unterscheidet sich DEX von Java-Bytecode?

DEX verwendet eine registerbasierte Architektur anstelle der stapelbasierten JVM, hat ein kompakteres Format (30% kleiner), fasst alle .class-Dateien in einer Datei mit einem einheitlichen Konstantenpool zusammen und verwendet 16-Bit-Indizes anstelle von 8-Bit-Indizes.

Was ist Smali?

Smali ist ein Assembler für DEX-Bytecode. Jede DEX-Anweisung hat eine Textdarstellung im Smali-Format. Das Werkzeug baksmali konvertiert DEX in Smali (Disassemblierung), und Smali assembliert Smali zurück in DEX.

Wie überprüft man die Anzahl der Methoden in DEX?

Der Gradle-Task countMethods oder das Plugin dex-method-counts zeigen die Anzahl der Methoden in jeder DEX-Datei. Der Befehl adb shell mit dumpsys zeigt ebenfalls Statistiken der geladenen DEX-Dateien für installierte Anwendungen.

Beeinflusst die Anzahl der DEX-Dateien die Leistung?

Ja, auf Geräten mit Android vor 8.0 verlangsamen mehrere DEX-Dateien den Anwendungsstart, da jede zusätzliche Datei separat geladen wird. Auf ART mit Android 8.0+ ist der Unterschied dank der dex2oat-Kompilierung in eine einzelne .oat-Datei minimal.

Kann DEX ohne Android ausgeführt werden?

Ja, es gibt Projekte wie dexplorer und Android-kompatible JVM-Implementierungen, die DEX-Bytecode außerhalb von Android ausführen können. Die meisten DEX-Dateien verwenden jedoch die Android-API, was sie für die Ausführung auf einer Standard-JVM ungeeignet macht.

Zusammenfassung

  • DEX ist ein Android-Bytecode-Format mit registerbasierter Architektur und kompakter Codedarstellung.
  • Struktur umfasst einen Header, Identifikatortabellen und einen Datenabschnitt mit Anweisungen.
  • Kompilierung zu DEX erfolgt über D8: .class → DEX mit Optimierungen und Zusammenführen von Konstantenpools.
  • ART kompiliert DEX bei der Installation in nativen Code (AOT) und beschleunigt so den Anwendungsstart.
  • Multidex löst das 65536-Methodenlimit durch Aufteilung auf mehrere DEX-Dateien.
  • Optimierung — R8 reduziert DEX um 20–40%, verschleiert Namen und entfernt toten Code.
  • Schutz — Verschleierung mit R8/ProGuard, DexGuard und O-LLVM verhindert die Dekompilierung von DEX.

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