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 in drei verschiedenen Zuständen vorliegen:
    • 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

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