In diesem Beitrag werden wir über die Android-Laufzeit sprechen. Insbesondere werde ich versuchen, kurz, aber kurz zu skizzieren, wie sich ART und Dalvik unterscheiden und wie sich die Android-Entwicklungstools im Laufe der Zeit verbessert haben. Das Thema ist eindeutig nicht neu, aber ich hoffe, es wird sich für diejenigen als nützlich erweisen, die gerade erst anfangen, sich damit zu beschäftigen. Wen kümmert es - willkommen bei Katze.
Virtuelle Maschine
Lassen Sie uns zunächst sehen, wie sich die JVM von der DVM unterscheidet.
Die Java Virtual Machine ist eine virtuelle Maschine, die Java-Bytecode unabhängig von der zugrunde liegenden Plattform ausführen kann. Es basiert auf dem Prinzip „Einmal schreiben, überall ausführen“. Java-Bytecode kann auf jedem Computer ausgeführt werden, der die JVM unterstützt.
Der Java-Compiler konvertiert Java-Dateien in Klassendateien (Bytecode). Der Bytecode wird an die JVM übergeben, die ihn zur Ausführung direkt auf der CPU zu Maschinencode kompiliert.
JVM-Funktionen:
- Es hat eine Stapelarchitektur: Ein Stapel wird als Datenstruktur verwendet, in der Methoden platziert und gespeichert werden. Es funktioniert in LIFO oder "Last in - First Out" oder "Last in, first out".
- Kann nur Klassendateien ausführen.
- Verwendet einen JIT-Compiler.
Die Dalvik Virtual Machine (DVM) ist eine Java Virtual Machine, die von Dan Bornstein und anderen als Teil der mobilen Android-Plattform entwickelt und geschrieben wurde.
Wir können sagen, dass Dalvik die Umgebung für die Ausführung von Android-Betriebssystemkomponenten und benutzerdefinierten Anwendungen ist. Jeder Prozess wird in einem eigenen isolierten Adressraum ausgeführt. Wenn ein Benutzer eine Anwendung startet (oder das Betriebssystem eine seiner Komponenten startet), erstellt der Dalvik-Kern der virtuellen Maschine (Zygote Dalvik VM) einen separaten, geschützten Prozess im gemeinsam genutzten Speicher, in dem die VM direkt als Umgebung zum Starten der Anwendung bereitgestellt wird. Mit anderen Worten, von innen sieht Android aus wie eine Reihe von virtuellen Dalvik-Maschinen, auf denen jeweils eine Anwendung ausgeführt wird.
Eigenschaften von DVM:
- Verwendet eine registergestützte Architektur: Die Datenstruktur, in der Methoden platziert werden, basiert auf Prozessorregistern. Aufgrund des Fehlens von POP- und PUSH-Operationen werden Anweisungen in einer registrierten virtuellen Maschine schneller ausgeführt als ähnliche Anweisungen in einer gestapelten virtuellen Maschine.
- Führt Bytecode im nativen Format aus: Android Dexer (wir werden weiter unten darauf eingehen) konvertiert Klassendateien in das Dex-Format, das für die Ausführung auf Dalvik VM optimiert ist. Im Gegensatz zu einer Klassendatei enthält eine Dex-Datei mehrere Klassen gleichzeitig.
Weitere Informationen zur DVM-Architektur finden Sie hier .
Android Dexer
Android-Entwickler wissen, dass das Konvertieren von Java-Bytecode in .dex-Bytecode für Android Runtime ein wichtiger Schritt beim Erstellen einer APK ist. Der Dex-Compiler arbeitet in der täglichen Anwendungsentwicklung meistens unter der Haube, wirkt sich jedoch direkt auf die Erstellungszeit der Anwendung, die Größe der Dex-Datei und die Laufzeitleistung aus.
Wie bereits erwähnt, enthält die Dex-Datei selbst mehrere Klassen gleichzeitig. Doppelte Zeilen und andere Konstanten, die in mehreren Klassendateien verwendet werden, sind nur aus Platzgründen enthalten. Java-Bytecode wird auch in einen alternativen Befehlssatz konvertiert, der von DVM verwendet wird. Die unkomprimierte Dex-Datei ist normalerweise einige Prozent kleiner als das komprimierte Java-Archiv (JAR), das aus denselben .class-Dateien abgerufen wird.
Anfangs wurden Klassendateien mit dem integrierten DX-Compiler in Dex-Dateien konvertiert. Ab Android Studio 3.1 wurde D8 jedoch zum Standard-Compiler . Im Vergleich zum DX-Compiler kompiliert D8 schneller und gibt kleinere Dex-Dateien aus, während zur Laufzeit eine bessere Anwendungsleistung erzielt wird. Der auf diese Weise erhaltene Dex-Bytecode wird mit dem Open-Source-Dienstprogramm ProGuard minimiert . Als Ergebnis erhalten wir die gleiche Dex-Datei, aber kleiner. Diese Dex-Datei wird dann verwendet, um die apk zu erstellen und schließlich auf einem Android-Gerät bereitzustellen.
Aber hinter D8 im Jahr 2018 kam R8, die in der Tat der gleiche D8 ist, nur mit Ergänzungen.
Wenn Sie mit Android Studio 3.4 und Android Gradle 3.4.0 oder höher arbeiten, wird Proguard nicht mehr zur Optimierung des Codes beim Kompilieren verwendet. Stattdessen funktioniert das Plugin standardmäßig mit R8, das das Verkleinern, Optimieren und Verschleiern von Code selbst ausführt. Obwohl R8 nur einen Teil der von Proguard bereitgestellten Funktionen bietet, können Sie die Konvertierung von Java-Bytecode in Dex-Bytecode einmal durchführen, wodurch die Erstellungszeit weiter verkürzt wird.
R8 und Code-Reduzierung
In der Regel verwenden Apps Bibliotheken von Drittanbietern wie Jetpack, Gson und Google Play Services. Wenn wir eine dieser Bibliotheken verwenden, verwendet die Anwendung häufig nur einen kleinen Teil jeder einzelnen Bibliothek. Ohne Verkleinerung des Codes wird der gesamte Bibliothekscode in Ihrer Anwendung gespeichert.
Es kommt vor, dass Entwickler ausführlichen Code verwenden, um die Lesbarkeit und Wartbarkeit einer Anwendung zu verbessern. Beispielsweise können aussagekräftige Variablennamen und ein Entwurfsmuster verwendet werden, um anderen das Verständnis des Codes zu erleichtern. Vorlagen führen jedoch tendenziell zu mehr Code als erforderlich.
Hier kommt der R8 zur Rettung. Dies kann die Größe der Anwendung erheblich reduzieren und sogar die Größe des Codes optimieren, der tatsächlich von der Anwendung verwendet wird.
Im Folgenden finden Sie als Beispiel die Zahlen aus dem Bericht Shrinking Your App with R8 , der auf dem Android Dev Summit '19 vorgestellt wurde:
So sah der Vergleich der Effizienz von R8 in der Beta-Release-Phase aus (entnommen aus dem Quell- Blog für Android-Entwickler ):
Weitere Details finden Sie hier in der Bürodokumentation und Bericht .
ART vs DVM in Android
DVM wurde speziell für mobile Geräte entwickelt und als virtuelle
Maschine zum Ausführen von Android-Anwendungen bis Android 4.4 Kitkat verwendet.
Ab dieser Version wurde ART als Laufzeit eingeführt und in Android 5.0 (Lollipop) ersetzte ART Dalvik vollständig.
Der Hauptunterschied zwischen ART und DVM besteht darin, dass ART die AOT-Kompilierung verwendet, während DVM die JIT-Kompilierung verwendet. Vor nicht allzu langer Zeit begann ART, einen Hybrid aus AOT und JIT zu verwenden. Schauen wir uns das genauer an.
DVM
- Verwendet die JIT-Kompilierung: Wann immer die Anwendung startet,
- Der Teil des Codes, der zum Ausführen der Anwendung benötigt wird, wird kompiliert. Der Rest des Codes wird dynamisch kompiliert. Dies verlangsamt den Start und Betrieb von Anwendungen, verkürzt jedoch die Installationszeit.
- , .
- , DVM, , , ART.
- , CPU.
- Dalvik “” 4.4.
ART
- AOT , . , .
- , .
- AOT , DVM.
- , - .
- Verbesserte Garbage Collection oder Garbage Collection. Bei der Verwendung von Dalvik mussten Garbage Collectors zwei Heap-Pässe ausführen, was zu einer schlechten UX führte. Im Fall von ART gibt es keine solche Situation: Es bereinigt den Heap einmal, um den Speicher zu konsolidieren.
Und ein kleines Diagramm von Dalvik vs ART:
JIT + AOT in ART
Die Android Runtime (ART) seit Android 7 enthält einen JIT-Compiler mit Code-Profiling. Der JIT-Compiler ergänzt den AOT-Compiler und verbessert die Laufzeitleistung, spart Speicherplatz und beschleunigt Anwendungs- und Systemaktualisierungen.
Dies geschieht folgendermaßen:
Anstatt die AOT-Kompilierung jeder Anwendung während der Installationsphase auszuführen, wird die Anwendung unter der Kontrolle einer virtuellen Maschine unter Verwendung eines JIT-Compilers ausgeführt (fast wie in Android <5.0), verfolgt jedoch, welche Abschnitte des Anwendungscodes werden am häufigsten ausgeführt. Diese Informationen werden dann verwendet, um diese Codeabschnitte von AOT zu kompilieren. Letzterer Vorgang wird nur ausgeführt, wenn das Smartphone während des Ladevorgangs inaktiv ist.
In einfachen Worten, jetzt arbeiten zwei völlig unterschiedliche Ansätze zusammen, was seine Vorteile bietet:
- Effizientere Kompilierung - Wenn die Anwendung in Echtzeit gestartet wird, hat der Compiler die Möglichkeit, viel mehr über seine Arbeit zu erfahren als durch statische Analysen. Daher werden für jede Situation geeignetere Optimierungsmethoden angewendet.
- Erhaltung des Arbeitsspeichers und des permanenten Speichers - Bytecode ist kompakter als Maschinencode. Wenn Sie nur bestimmte Abschnitte der Anwendung AOT-kompilieren und keine Anwendungen kompilieren, die der Benutzer nicht verwendet, können Sie erheblich NAND-Speicherplatz sparen.
- dramatischer Anstieg der Installation und der ersten Startgeschwindigkeit nach dem Systemupdate - keine AOT-Kompilierung, keine Verzögerung.
Lesen Sie mehr über die Umsetzung der JIT - Compiler in ART hier .
Fazit
In diesem Artikel habe ich versucht, einen Blick auf die Hauptunterschiede zwischen Dalvik und ART zu werfen und allgemein zu untersuchen, wie Android seine Entwicklungstools im Laufe der Zeit verbessert hat.
ART befindet sich noch in der Entwicklung. Neue Funktionen werden hinzugefügt, um die Benutzererfahrung für Benutzer und Entwickler zu verbessern.
Wenn es hilfreich war, lass es mich in den Kommentaren wissen.