ART konfigurieren

Auf dieser Seite wird erläutert, wie ART und seine Kompilierungsoptionen konfiguriert werden. Zu den hier behandelten Themen gehören die Konfiguration der Vorkompilierung des Systemabbilds, die dex2oat-Kompilierungsoptionen und die Frage, wie Sie den Speicherplatz der Systempartition, den Speicherplatz der Datenpartition und die Leistung ausgleichen können.

Siehe ART und Dalvik , das ausführbare Dalvik-Format und die restlichen Seiten auf source.android.com, um mit ART zu arbeiten. Siehe Überprüfen des App-Verhaltens in der Android-Laufzeit (ART) , um sicherzustellen, dass Ihre Apps ordnungsgemäß funktionieren.

Wie KUNST funktioniert

ART verwendet AOT-Kompilierung (Ahead-of-Time) und ab Android 7.0 (Nougat oder N) eine Hybridkombination aus AOT, Just-in-Time-Kompilierung (JIT) und profilgeführter Kompilierung. Die Kombination all dieser Kompilierungsmodi ist konfigurierbar und wird in diesem Abschnitt besprochen. Beispielsweise werden Pixel-Geräte mit dem folgenden Kompilierungsablauf konfiguriert:

  1. Eine Anwendung wird zunächst ohne AOT-Kompilierung installiert. Die ersten Male, wenn die Anwendung ausgeführt wird, wird sie interpretiert, und häufig ausgeführte Methoden werden JIT-kompiliert.
  2. Wenn das Gerät im Leerlauf ist und lädt, wird ein Kompilierungs-Daemon ausgeführt, um häufig verwendeten Code auf der Grundlage eines Profils zu kompilieren, das während der ersten Läufe generiert wurde.
  3. Der nächste Neustart einer Anwendung verwendet den profilgeführten Code und vermeidet die JIT-Kompilierung zur Laufzeit für bereits kompilierte Methoden. Methoden, die während der neuen Läufe JIT-kompiliert werden, werden dem Profil hinzugefügt, das dann vom Kompilierungs-Daemon abgeholt wird.

ART besteht aus einem Compiler (dem Tool dex2oat ) und einer Laufzeitumgebung ( libart.so ), die zum Starten von Zygote geladen wird. Das dex2oat Tool nimmt eine APK-Datei und generiert eine oder mehrere Kompilierungsartefaktdateien, die die Laufzeit lädt. Die Anzahl der Dateien, ihre Erweiterungen und Namen können sich je nach Version ändern, aber ab der Version von Android O werden folgende Dateien generiert:

  • .vdex : enthält den unkomprimierten DEX-Code der APK mit einigen zusätzlichen Metadaten zur Beschleunigung der Überprüfung.
  • .odex : enthält AOT-kompilierten Code für Methoden in der APK.
  • .art (optional) : enthält ART-interne Darstellungen einiger Zeichenfolgen und Klassen, die in der APK aufgeführt sind und zur Beschleunigung des Anwendungsstarts verwendet werden.

Zusammenstellungsoptionen

Zusammenstellungsoptionen für ART sind in zwei Kategorien unterteilt:

  1. System-ROM-Konfiguration: Welcher Code wird beim Erstellen eines Systemabbilds AOT-kompiliert.
  2. Laufzeitkonfiguration: wie ART Anwendungen auf einem Gerät kompiliert und ausführt.

Eine zentrale ART-Option zum Konfigurieren dieser beiden Kategorien sind Compiler-Filter . Compilerfilter steuern, wie ART DEX-Code kompiliert, und sind eine Option, die an das dex2oat Tool übergeben wird. Ab Android O gibt es vier offiziell unterstützte Filter:

  • Verify : Führen Sie nur die DEX-Code-Verifizierung aus.
  • quicken : Führen Sie die DEX-Code-Überprüfung aus und optimieren Sie einige DEX-Anweisungen, um eine bessere Interpreterleistung zu erzielen.
  • Geschwindigkeit : Führen Sie die DEX-Code-Überprüfung aus und kompilieren Sie alle Methoden AOT.
  • speed-profile : Führen Sie die in einer Profildatei aufgelisteten DEX-Code-Verifizierungs- und AOT-Kompilierungsmethoden aus.

System-ROM-Konfiguration

Es gibt eine Reihe von ART-Build-Optionen zum Konfigurieren eines System-ROM. Wie Sie diese Optionen konfigurieren, hängt vom verfügbaren Speicherplatz für /system und der Anzahl der vorinstallierten Anwendungen ab. Die JARs/APKs, die in ein System-ROM kompiliert werden, können in vier Kategorien unterteilt werden:

  • Boot-Classpath-Code: standardmäßig mit dem Speed- Compiler-Filter kompiliert.
  • Systemservercode: standardmäßig mit dem Speed- Compiler-Filter kompiliert.
  • Produktspezifische Kernanwendungen: standardmäßig mit dem Speed- Compiler-Filter kompiliert.
  • Alle anderen Anwendungen: standardmäßig mit dem Quicken -Compiler-Filter kompiliert.

Makefile-Optionen

  • WITH_DEXPREOPT
  • Ob dex2oat auf DEX-Code aufgerufen wird, der auf dem Systemabbild installiert ist. Standardmäßig aktiviert.

  • DONT_DEXPREOPT_PREBUILTS (seit Android L)
  • Durch Aktivieren von DONT_DEXPREOPT_PREBUILTS verhindert, dass die vorgefertigten Elemente vorab optimiert werden. Dies sind Apps, für die in ihrer Android.mk include $(BUILD_PREBUILT) angegeben ist, z. B. Gmail. Das Überspringen der Voroptimierung von vorgefertigten Apps, die wahrscheinlich über Google Play aktualisiert werden, spart /system , verlängert jedoch die Zeit für den ersten Start.

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (seit Android 9)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER gibt den standardmäßigen Compiler-Filter für voroptimierte Anwendungen an. Dies sind Apps, für die in ihrer Android.mk include $(BUILD_PREBUILT) angegeben ist, z. B. Gmail. Wenn nicht angegeben, ist der Standardwert schneller.

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (neu in Android O MR1)
  • Das Aktivieren WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY optimiert nur den Boot-Klassenpfad und die Systemserver-JAR-Dateien vorab.

  • LOCAL_DEX_PREOPT
  • Die Voroptimierung kann auch auf individueller App-Basis aktiviert oder deaktiviert werden, indem die Option LOCAL_DEX_PREOPT in der Moduldefinition angegeben wird. Dies kann nützlich sein, um die Voroptimierung von Apps zu deaktivieren, die möglicherweise sofort Google Play-Updates erhalten, da die Updates den voroptimierten Code im Systemabbild überflüssig machen würden. Dies ist auch nützlich, um Platz bei OTAs für Hauptversions-Upgrades zu sparen, da Benutzer möglicherweise bereits neuere Versionen von Apps in der Datenpartition haben.

    LOCAL_DEX_PREOPT unterstützt die Werte „true“ oder „false“, um die Voroptimierung zu aktivieren bzw. zu deaktivieren. Außerdem kann „Nostripping“ angegeben werden, wenn die classes.dex die Datei „classes.dex“ nicht aus der APK- oder JAR-Datei entfernen soll. Normalerweise wird diese Datei entfernt, da sie nach der Voroptimierung nicht mehr benötigt wird, aber diese letzte Option ist notwendig, damit APK-Signaturen von Drittanbietern gültig bleiben.

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • Übergibt Optionen an dex2oat , um zu steuern, wie das Boot-Image kompiliert wird. Es kann verwendet werden, um angepasste Bildklassenlisten, kompilierte Klassenlisten und Compilerfilter anzugeben.

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • Übergibt Optionen an dex2oat , um zu steuern, wie alles außer dem Boot-Image kompiliert wird.

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • Bietet die Möglichkeit, dex2oat Optionen für ein bestimmtes Modul und eine bestimmte Produktkonfiguration zu übergeben. Es wird in der device.mk -Datei eines Produkts durch $(call add-product-dex-preopt-module-config,<modules>,<option>) festgelegt, wobei <modules> eine Liste von LOCAL_MODULE- und LOCAL_PACKAGE-Namen für JAR und APK ist Dateien bzw.

  • PRODUCT_DEXPREOPT_SPEED_APPS (New in Android O)
  • Liste der Anwendungen, die als Kern der Produkte identifiziert wurden und die mit dem Speed- Compiler-Filter kompiliert werden sollten. Beispielsweise erhalten dauerhafte Apps wie SystemUI nur beim nächsten Neustart die Möglichkeit, die profilgeführte Kompilierung zu verwenden, sodass es für das Produkt möglicherweise besser ist, diese Apps immer AOT-kompiliert zu haben.

  • PRODUCT_SYSTEM_SERVER_APPS (New in Android O)
  • Liste der Anwendungen, die vom Systemserver geladen werden. Diese Anwendungen werden standardmäßig mit dem Speed- Compiler-Filter kompiliert.

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD(Post Android O)
  • Ob eine Debug-Version von ART auf dem Gerät enthalten sein soll. Standardmäßig ist dies für Userdebug- und Eng-Builds aktiviert. Das Verhalten kann überschrieben werden, indem die Option explizit auf true oder false gesetzt wird.

    Standardmäßig verwendet das Gerät die Nicht-Debug-Version ( libart.so ). Setzen Sie zum Umschalten die Systemeigenschaft persist.sys.dalvik.vm.lib.2 auf libartd.so .

  • WITH_DEXPREOPT_PIC (Removed in Android O)
  • In Android 5.1.0 bis Android 6.0.1 kann WITH_DEXPREOPT_PIC angegeben werden, um positionsunabhängigen Code (PIC) zu aktivieren. Damit muss kompilierter Code aus dem Image nicht von /system nach /data/dalvik-cache verschoben werden, was Platz in der Datenpartition spart. Es gibt jedoch eine geringfügige Auswirkung auf die Laufzeit, da eine Optimierung deaktiviert wird, die positionsabhängigen Code nutzt. Normalerweise sollten Geräte, die Platz in /data sparen möchten, die PIC-Kompilierung aktivieren.

    In Android 7.0 war die PIC-Kompilierung standardmäßig aktiviert.

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (in Android O MR1 entfernt)
  • Diese Option wurde durch WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ersetzt, das auch die Systemserver-JAR-Dateien vorwählt.

Boot-Classpath-Konfiguration

  • Vorinstallierte Klassenliste
  • Die vorgeladene Klassenliste ist eine Liste von Klassen, die die Zygote beim Start initialisiert. Dadurch muss jede App diese Klasseninitialisierer nicht separat ausführen, sodass sie schneller gestartet und Seiten im Arbeitsspeicher gemeinsam genutzt werden können. Die Listendatei der vorinstallierten Klassen befindet sich standardmäßig unter frameworks/base/config/preloaded-classes und enthält eine Liste, die für die typische Telefonnutzung optimiert ist. Dies kann bei anderen Geräten wie Wearables anders sein und muss entsprechend abgestimmt werden. Seien Sie vorsichtig, wenn Sie dies tunen; Das Hinzufügen zu vieler Klassen verschwendet Speicherplatz, wenn nicht verwendete Klassen geladen werden. Wenn zu wenige Klassen hinzugefügt werden, muss jede App ihre eigene Kopie haben, was wiederum Speicherplatz verschwendet.

    Beispielverwendung (in der Datei „device.mk“ des Produkts):

    PRODUCT_COPY_FILES += <filename>:system/etc/preloaded-classes
    

    Hinweis: Diese Zeile muss platziert werden, bevor Produktkonfigurations-Makefiles geerbt werden, die das Standard-Makefile von: build/target/product/base.mk

  • Liste der Bildklassen
  • Die Liste der Bildklassen ist eine Liste von Klassen, die dex2oat im Voraus initialisiert und in der Datei boot.art speichert. Dadurch kann die Zygote diese Ergebnisse beim Start aus der boot.art-Datei laden, anstatt die Initialisierer für diese Klassen selbst während des Vorladens auszuführen. Ein Schlüsselmerkmal dabei ist, dass die aus dem Image geladenen und von Prozessen gemeinsam genutzten Seiten sauber sein können, sodass sie in Situationen mit wenig Arbeitsspeicher problemlos ausgetauscht werden können. In L verwendet die Liste der Bildklassen standardmäßig dieselbe Liste wie die vorgeladene Klassenliste. Ab Post-L in AOSP kann eine benutzerdefinierte Bildklassenliste angegeben werden mit:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Beispielverwendung (in der Datei „ device.mk “ des Produkts):

    PRODUCT_DEX_PREOPT_BOOT_FLAGS += --image-classes=<filename>
    
  • Kompilierte Klassenliste
  • In Post-L-AOSP kann eine Teilmenge von Klassen aus dem Boot-Klassenpfad angegeben werden, die während der Voroptimierung unter Verwendung der kompilierten Klassenliste kompiliert werden sollen. Dies kann eine nützliche Option für Geräte sein, die sehr wenig Platz haben und nicht in das gesamte voroptimierte Boot-Image passen. Notenklassen, die nicht in dieser Liste angegeben sind, werden jedoch nicht kompiliert – nicht einmal auf dem Gerät – und müssen interpretiert werden, was möglicherweise die Laufzeitleistung beeinträchtigt. Standardmäßig sucht dex2oat nach einer kompilierten Klassenliste in $OUT/system/etc/compiled-classes, sodass eine benutzerdefinierte Liste von device.mk an diesen Ort kopiert werden kann. Ein bestimmter Dateispeicherort kann auch angegeben werden mit:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Beispielverwendung (in der Datei „ device.mk “ des Produkts):

    PRODUCT_COPY_FILES += <filename>:system/etc/compiled-classes
    

    Hinweis: Diese Zeile muss platziert werden, bevor Produktkonfigurations-Makefiles geerbt werden, die das Standard-Makefile von: build/target/product/base.mk

Laufzeitkonfiguration

Jit-Optionen

Die folgenden Optionen wirken sich nur auf Android-Releases aus, bei denen der ART JIT-Compiler verfügbar ist.

  • dalvik.vm.usejit: ob JIT aktiviert ist oder nicht.
  • dalvik.vm.jitinitialsize (Standard 64 KB): die anfängliche Kapazität des Code-Cache. Der Code-Cache wird regelmäßig GC und bei Bedarf erhöht.
  • dalvik.vm.jitmaxsize (Standard 64 MB): die maximale Kapazität des Code-Cache.
  • dalvik.vm.jitthreshold: (Standard 10000) – Dies ist der Schwellenwert, den der „Hotness“-Zähler einer Methode überschreiten muss, damit die Methode JIT-kompiliert wird. Der "Hotness"-Zähler ist eine interne Metrik der Laufzeit. Es umfasst die Anzahl der Aufrufe, Rückwärtsverzweigungen und andere Faktoren.
  • dalvik.vm.usejitprofiles: ob JIT-Profile aktiviert sind oder nicht; Dies kann auch dann verwendet werden, wenn dalvik.vm.usejit falsch ist. Beachten Sie, dass, wenn dies falsch ist, der Compiler-Filter speed-profile keine AOT-kompiliert eine Methode und gleichbedeutend mit quicken ist.
  • dalvik.vm.jitprithreadweight (standardmäßig dalvik.vm.jitthreshold / 20) – Die Gewichtung der JIT-„Samples“ (siehe jitthreshold) für den Anwendungs-UI-Thread. Wird verwendet, um die Kompilierung von Methoden zu beschleunigen, die sich direkt auf die Benutzererfahrung bei der Interaktion mit der App auswirken.
  • dalvik.vm.jittransitionweight: (standardmäßig dalvik.vm.jitthreshold / 10) die Gewichtung des Methodenaufrufs, der zwischen Kompiliercode und Interpreter wechselt. Dadurch wird sichergestellt, dass die beteiligten Methoden kompiliert werden, um Übergänge (die teuer sind) zu minimieren.

Paket-Manager-Optionen

Seit Android 7.0 gibt es eine generische Möglichkeit, die Ebene der Kompilierung/Verifizierung anzugeben, die in verschiedenen Phasen stattgefunden hat. Die Kompilierungsebenen können über die Systemeigenschaften konfiguriert werden, wobei die Standardwerte sind:

  • pm.dexopt.install=speed-profile
  • Dies ist der Kompilierungsfilter, der beim Installieren von Anwendungen über Google Play verwendet wird. Wir empfehlen, den Installationsfilter auf Geschwindigkeitsprofil einzustellen, um die Verwendung von Profilen aus den dex-Metadatendateien zu ermöglichen. Beachten Sie, dass, wenn ein Profil nicht bereitgestellt wird oder wenn es leer ist, speed-profile gleichbedeutend mit quicken ist.

  • pm.dexopt.bg-dexopt=speed-profile
  • Dies ist der Kompilierungsfilter, der verwendet wird, wenn das Gerät im Leerlauf ist, aufgeladen und vollständig aufgeladen wird. Probieren Sie den Geschwindigkeitsprofil- Compilerfilter aus, um die profilgeführte Kompilierung zu nutzen und Speicherplatz zu sparen.

  • pm.dexopt.boot=verify
  • Der Kompilierungsfilter, der nach einem Over-the-Air-Update verwendet wird. Wir empfehlen dringend , den Compiler-Filter für diese Option zu überprüfen , um sehr lange Startzeiten zu vermeiden.

  • pm.dexopt.first-boot=quicken
  • Der Kompilierungsfilter zum ersten Mal, wenn das Gerät überhaupt bootet. Der hier verwendete Filter wirkt sich nur auf die Bootzeit nach der Werkseinstellung aus. Wir empfehlen den Filter Quicken dafür, um lange Wartezeiten zu vermeiden, bevor ein Benutzer das Telefon zum ersten Mal benutzt. Beachten Sie, dass pm.dexopt.first-boot keine Auswirkung hat, wenn alle Anwendungen in /system bereits mit dem Quicken -Compilerfilter oder mit dem Speed- oder Speed-Profile- Compilerfilter kompiliert wurden.

Dex2oat-Optionen

Beachten Sie, dass sich diese Optionen auf dex2oat während der Kompilierung auf dem Gerät sowie während der Voroptimierung auswirken, während die meisten der oben besprochenen Optionen nur die Voroptimierung betreffen.

So steuern dex2oat , während es das Boot-Image kompiliert:

  • dalvik.vm.image-dex2oat-Xms: anfängliche Heap-Größe
  • dalvik.vm.image-dex2oat-Xmx: maximale Heap-Größe
  • dalvik.vm.image-dex2oat-filter: Compiler-Filteroption
  • dalvik.vm.image-dex2oat-threads: Anzahl der zu verwendenden Threads

So steuern dex2oat , während es alles außer dem Boot-Image kompiliert:

  • dalvik.vm.dex2oat-Xms: anfängliche Heap-Größe
  • dalvik.vm.dex2oat-Xmx: maximale Heap-Größe
  • dalvik.vm.dex2oat-filter: Compiler-Filteroption

Bei Veröffentlichungen bis Android 6.0 wird eine zusätzliche Option bereitgestellt, um alles außer dem Boot-Image zu kompilieren:

  • dalvik.vm.dex2oat-threads: Anzahl der zu verwendenden Threads

Ab Android 6.1 werden dies zwei zusätzliche Optionen, um alles außer dem Boot-Image zu kompilieren:

  • dalvik.vm.boot-dex2oat-threads: Anzahl der während des Bootvorgangs zu verwendenden Threads
  • dalvik.vm.dex2oat-threads: Anzahl der nach dem Booten zu verwendenden Threads

Ab Android 7.1 stehen zwei Optionen zur Verfügung, um zu steuern, wie Speicher verwendet wird, wenn alles außer dem Boot-Image kompiliert wird:

  • dalvik.vm.dex2oat-very-large: minimale Gesamtgröße der dex-Datei in Bytes, um die AOT-Kompilierung zu deaktivieren
  • dalvik.vm.dex2oat-swap: dex2oat-Auslagerungsdatei verwenden (für Geräte mit wenig Speicher)

Die Optionen, die die anfängliche und maximale Heap-Größe für dex2oat , sollten nicht reduziert werden, da sie einschränken könnten, welche Anwendungen kompiliert werden können.

Ab Android 11 werden drei CPU-Affinitätsoptionen bereitgestellt, um zu ermöglichen, dass Compiler-Threads auf eine bestimmte Gruppe von CPUs beschränkt werden:

  • dalvik.vm.boot-dex2oat-cpu-set: CPUs, die während des Bootens dex2oat-Threads ausführen
  • dalvik.vm.image-dex2oat-cpu-set: CPUs, auf denen dex2oat ausgeführt wird, während das Boot-Image kompiliert wird
  • dalvik.vm.dex2oat-cpu-set: CPUs, die nach dem Booten dex2oat-Threads ausführen

Die CPUs sollten als durch Kommas getrennte Liste von CPU-IDs angegeben werden. Um beispielsweise auf den CPUs 0-3 auf dex2oat zu laufen, setzen Sie:

dalvik.vm.dex2oat-cpu-set=0,1,2,3

Beim Festlegen der CPU-Affinitätseigenschaften empfehlen wir, die entsprechende Eigenschaft für die Anzahl der dex2oat-Threads an die Anzahl der ausgewählten CPUs anzupassen, um unnötige Speicher- und E/A-Konflikte zu vermeiden:

dalvik.vm.dex2oat-cpu-set=0,1,2,3
dalvik.vm.dex2oat-threads=4

Ab Android 12 wurden die folgenden Optionen hinzugefügt:

  • dalvik.vm.ps-min-first-save-ms: Die Zeit, die darauf gewartet werden muss, dass die Laufzeit ein Profil der Anwendung generiert, wenn die Anwendung zum ersten Mal gestartet wird
  • dalvik.vm.ps-min-save-period-ms: die Mindestzeit, die gewartet werden muss, bevor das Profil einer App aktualisiert wird
  • dalvik.vm.systemservercompilerfilter: Der Compilerfilter, den das Gerät beim Neukompilieren des Systemservers verwendet

A/B-spezifische Konfiguration

ROM-Konfiguration

Ab Android 7.0 können Geräte zwei Systempartitionen verwenden, um A/B- Systemupdates zu aktivieren . Um die Größe der Systempartition zu sparen, können die voreingestellten Dateien auf der ungenutzten zweiten Systempartition installiert werden. Sie werden dann beim ersten Booten auf die Datenpartition kopiert.

Beispielverwendung (in device-common.mk ):

PRODUCT_PACKAGES += \
     cppreopts.sh
PRODUCT_PROPERTY_OVERRIDES += \
     ro.cp_system_other_odex=1

Und in BoardConfig.mk des Geräts:

BOARD_USES_SYSTEM_OTHER_ODEX := true

Beachten Sie, dass Boot-Klassenpfadcode, Systemservercode und produktspezifische Kernanwendungen immer auf der Systempartition kompiliert werden. Standardmäßig werden alle anderen Anwendungen auf die unbenutzte zweite Systempartition kompiliert. Dies kann mit dem SYSTEM_OTHER_ODEX_FILTER gesteuert werden, der standardmäßig einen Wert von hat:

SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%

Hintergrund dexopt OTA

Bei A/B-fähigen Geräten können Anwendungen im Hintergrund kompiliert werden, um sie auf das neue Systemabbild zu aktualisieren. Siehe App-Kompilierung im Hintergrund , um optional das Kompilierungsskript und die Binärdateien in das Systemabbild aufzunehmen. Der für diese Zusammenstellung verwendete Kompilierungsfilter wird gesteuert mit:

pm.dexopt.ab-ota=speed-profile

Wir empfehlen die Verwendung von Speed-Profile , um die Vorteile der profilgeführten Kompilierung zu nutzen und Speicherplatz zu sparen.