Implementieren Sie den ART-Just-in-Time-Compiler

Android Runtime (ART) umfasst einen Just-in-Time-Compiler (JIT) mit Codeprofilierung, der die Leistung von Android-Anwendungen während der Ausführung kontinuierlich verbessert. Der JIT-Compiler ergänzt den aktuellen AOT-Compiler (Ahead-of-Time) von ART und verbessert die Laufzeitleistung, spart Speicherplatz und beschleunigt Anwendungs- und Systemaktualisierungen. Es verbessert auch den AOT-Compiler, indem es eine Systemverlangsamung während automatischer Anwendungsaktualisierungen oder eine Neukompilierung von Anwendungen während Over-the-Air-Updates (OTA) vermeidet.

Obwohl JIT und AOT denselben Compiler mit ähnlichen Optimierungen verwenden, ist der generierte Code möglicherweise nicht identisch. JIT nutzt Laufzeittypinformationen, kann ein besseres Inlining durchführen und ermöglicht die On-Stack-Replacement-Kompilierung (OSR), was alles zu leicht unterschiedlichem Code führt.

JIT-Architektur

JIT-Architektur
Abbildung 1. JIT-Architektur.

JIT-Kompilierung

Die JIT-Kompilierung umfasst die folgenden Aktivitäten:

Profilgeführte Komp
Abbildung 2. Profilgesteuerte Kompilierung.
  1. Der Benutzer führt die App aus, die dann ART auslöst, die .dex Datei zu laden.
    • Wenn die .oat Datei (die AOT-Binärdatei für die .dex Datei) verfügbar ist, verwendet ART sie direkt. Obwohl .oat Dateien regelmäßig generiert werden, enthalten sie nicht immer kompilierten Code (AOT-Binärdatei).
    • Wenn die .oat Datei keinen kompilierten Code enthält, wird ART über JIT und den Interpreter ausgeführt, um die .dex Datei auszuführen.
  2. JIT ist für alle Anwendungen aktiviert, die nicht gemäß dem speed kompiliert werden (der besagt: „Kompilieren Sie so viel wie möglich aus der App“).
  3. Die JIT-Profildaten werden in einer Datei in einem Systemverzeichnis gespeichert, auf das nur die Anwendung zugreifen kann.
  4. Der AOT-Kompilierungsdämon ( dex2oat ) analysiert diese Datei, um ihre Kompilierung voranzutreiben.

    JIT-Daemon
    Abbildung 3. JIT-Daemon-Aktivitäten.

Der Google Play-Dienst ist ein Beispiel für andere Anwendungen, die sich ähnlich wie gemeinsam genutzte Bibliotheken verhalten.

JIT-Workflow

JIT-Architektur
Abbildung 4. JIT-Datenfluss.
  • Profilierungsinformationen werden im Code-Cache gespeichert und unter Speicherdruck der Garbage Collection unterzogen.
    • Es gibt keine Garantie dafür, dass ein Snapshot, der erstellt wurde, als die Anwendung im Hintergrund lief, vollständige Daten enthält (d. h. alles, was per JIT verarbeitet wurde).
    • Es wird nicht versucht, sicherzustellen, dass alles aufgezeichnet wird (da dies Auswirkungen auf die Laufzeitleistung haben kann).
  • Methoden können drei verschiedene Zustände haben:
    • interpretiert (Dex-Code)
    • JIT kompiliert
    • AOT zusammengestellt
    Wenn sowohl JIT- als auch AOT-Code vorhanden sind (z. B. aufgrund wiederholter Deoptimierungen), wird der JIT-Code bevorzugt.
  • Der Speicherbedarf zum Ausführen von JIT ohne Beeinträchtigung der Leistung der Vordergrund-App hängt von der jeweiligen App ab. Große Apps benötigen mehr Speicher als kleine Apps. Im Allgemeinen stabilisieren sich große Apps bei etwa 4 MB.

Aktivieren Sie die JIT-Protokollierung

Führen Sie die folgenden Befehle aus, um die JIT-Protokollierung zu aktivieren:

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Deaktivieren Sie JIT

Um JIT zu deaktivieren, führen Sie die folgenden Befehle aus:

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Kompilierung erzwingen

Um die Kompilierung zu erzwingen, führen Sie Folgendes aus:

adb shell cmd package compile

Häufige Anwendungsfälle zum Erzwingen der Kompilierung eines bestimmten Pakets:

  • Profilbasiert:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Vollständig:
    adb shell cmd package compile -m speed -f my-package
    

Häufige Anwendungsfälle für die erzwungene Kompilierung aller Pakete:

  • Profilbasiert:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Vollständig:
    adb shell cmd package compile -m speed -f -a
    

Profildaten löschen

Auf Android 13 oder früher

Führen Sie Folgendes aus, um lokale Profildaten zu löschen und kompilierten Code zu entfernen:

adb shell pm compile --reset 

Auf Android 14 oder höher

So löschen Sie nur lokale Profildaten:

adb shell pm art clear-app-profiles 

Hinweis: Im Gegensatz zum Befehl für Android 13 oder früher löscht dieser Befehl keine externen Profildaten („.dm“), die mit der App installiert sind.

Führen Sie Folgendes aus, um lokale Profildaten zu löschen und aus lokalen Profildaten generierten kompilierten Code zu entfernen (d. h. auf den Installationsstatus zurückzusetzen):

adb shell pm compile --reset 

Hinweis: Dieser Befehl entfernt keinen kompilierten Code, der aus externen Profildaten („.dm“) generiert wurde, die mit der App installiert wurden.

Um den gesamten kompilierten Code zu löschen, führen Sie diesen Befehl aus:

adb shell cmd package compile -m verify -f 

Hinweis: Dieser Befehl behält lokale Profildaten bei.