Implementieren des ART Just-In-Time (JIT)-Compilers

Android Runtime (ART) enthält einen Just-in-Time (JIT)-Compiler mit Codeprofilerstellung, der die Leistung von Android-Anwendungen während der Ausführung kontinuierlich verbessert. Der JIT-Compiler ergänzt den aktuellen AOT-Compiler 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 die Neukompilierung von Anwendungen während Over-the-Air (OTA)-Aktualisierungen vermeidet.

Obwohl JIT und AOT denselben Compiler mit ähnlichen Optimierungen verwenden, ist der generierte Code möglicherweise nicht identisch. JIT nutzt Laufzeittypinformationen, kann besseres Inlining durchführen und ermöglicht die Kompilierung beim Stapelaustausch (OSR), die alle etwas anderen Code generieren.

JIT-Architektur

JIT-Architektur
Abbildung 1. JIT-Architektur.

JIT-Kompilierung

Die JIT-Zusammenstellung umfasst die folgenden Aktivitäten:

Profilgeführte Komp
Abbildung 2. Profilgeführte Zusammenstellung.
  1. Der Benutzer führt die App aus, die dann ART auslöst, um 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, durchläuft ART JIT und den Interpreter, um die .dex Datei auszuführen.
  2. JIT ist für jede Anwendung aktiviert, die nicht gemäß dem speed kompiliert wurde (der besagt, dass „so viel wie möglich aus der App kompilieren“).
  3. Die JIT-Profildaten werden in eine Datei in einem Systemverzeichnis ausgegeben, auf das nur die Anwendung zugreifen kann.
  4. Der AOT-Kompilierungsdämon ( dex2oat ) parst diese Datei, um ihre Kompilierung voranzutreiben.

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

Der Google Play-Dienst ist ein Beispiel, das von anderen Anwendungen verwendet wird, die sich ähnlich wie gemeinsam genutzte Bibliotheken verhalten.

JIT-Workflow

JIT-Architektur
Abbildung 4. JIT-Datenfluss.
  • Profiling-Informationen 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 (dh alles, was JITed war).
    • Es wird nicht versucht sicherzustellen, dass alles aufgezeichnet wird (da dies die Laufzeitleistung beeinträchtigen kann).
  • Methoden können sich in drei verschiedenen Zuständen befinden:
    • 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 Arbeitsspeicherbedarf zum Ausführen von JIT ohne Beeinträchtigung der Leistung der Vordergrund-App hängt von der betreffenden App ab. Große Apps benötigen mehr Speicher als kleine Apps. Im Allgemeinen stabilisieren sich große Apps bei etwa 4 MB.

Aktivieren der 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

JIT deaktivieren

Führen Sie die folgenden Befehle aus, um JIT zu deaktivieren:

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, um das Kompilieren eines bestimmten Pakets zu erzwingen:

  • 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 das erzwungene Kompilieren 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

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

  • Für ein Paket:
    adb shell cmd package compile --reset my-package
    
  • Für alle Pakete:
    adb shell cmd package compile --reset -a