Sehen Sie sich zuerst einen allgemeinen Überblick über den ART-Dienst an.
Ab Android 14 wird On-Device-AOT-Kompilierung für Apps (auch „Dexopt“ genannt) werden von ART Service verarbeitet. Der ART Service ist Teil der ART. und können über Systemeigenschaften und APIs angepasst werden.
Systemeigenschaften
ART Service unterstützt alle relevanten dex2oat-Optionen.
Außerdem unterstützt der ART-Dienst die folgenden Systemeigenschaften:
pm.dexopt.<Grund>
Hierbei handelt es sich um eine Reihe von Systemeigenschaften, die die Standard-Compiler-Filter bestimmen für alle vordefinierten Kompilierungsgründe, die in Dexopt-Szenarien beschrieben sind.
Weitere Informationen finden Sie unter Compiler-Filter.
Die Standardwerte lauten:
pm.dexopt.first-boot=verify
pm.dexopt.boot-after-ota=verify
pm.dexopt.boot-after-mainline-update=verify
pm.dexopt.bg-dexopt=speed-profile
pm.dexopt.inactive=verify
pm.dexopt.cmdline=verify
pm.dexopt.shared (Standard: Geschwindigkeit)
Dies ist der Fallback-Compiler-Filter für Apps, die von anderen Apps verwendet werden.
Prinzipiell führt ART Service eine profilgestützte Kompilierung (speed-profile
) für
wenn möglich, in der Regel während der Hintergrund-Deaktivierung. Es gibt jedoch
Einige Apps, die von anderen Apps verwendet werden (entweder über <uses-library>
oder geladen)
dynamisch mit Context#createPackageContext
mit
CONTEXT_INCLUDE_CODE
) Solche Apps dürfen keine lokalen
aus Datenschutzgründen nicht mehr zu sehen ist.
Wenn bei einer solchen App eine profilgestützte Kompilierung angefordert wird, muss zuerst der ART-Dienst verwendet werden.
versucht, ein Cloud-Profil zu verwenden. Wenn kein Cloud-Profil vorhanden ist, ART Service
verwendet den von pm.dexopt.shared
angegebenen Compiler-Filter.
Wenn die angeforderte Kompilierung nicht über ein Profil erstellt wird, hat diese Property keine Auswirkungen.
pm.dexopt.<reason>.concurrency (Standard: 1)
Dies ist die Anzahl der dex2oat-Aufrufe für eine bestimmte vordefinierte Kompilierung
(first-boot
, boot-after-ota
, boot-after-mainline-update
und
bg-dexopt
.
Beachten Sie, dass der Effekt dieser Option mit
dex2oat-Optionen zur Ressourcennutzung (dalvik.vm.*dex2oat-threads
,
dalvik.vm.*dex2oat-cpu-set
und die Aufgabenprofile):
dalvik.vm.*dex2oat-threads
steuert die Anzahl der Threads für jeden dex2oat. -Aufruf, währendpm.dexopt.<reason>.concurrency
die Anzahl der dex2oat-Aufrufe. Das heißt, die maximale Anzahl gleichzeitiger Threads ist das Produkt der beiden Systemeigenschaften.dalvik.vm.*dex2oat-cpu-set
und die Aufgabenprofile binden immer den CPU-Kern. Auslastung, unabhängig von der maximalen Anzahl gleichzeitiger Threads (im Folgenden oben).
Ein einzelner dex2oat-Aufruf nutzt möglicherweise nicht alle CPU-Kerne, unabhängig davon,
von dalvik.vm.*dex2oat-threads
. Daher erhöht sich die Anzahl der dex2oat-
Aufrufe (pm.dexopt.<reason>.concurrency
) können CPU-Kerne besser nutzen, um
den Gesamtfortschritt von Dexopt zu beschleunigen. Dies ist besonders nützlich, wenn Sie
starten.
Bei zu vielen dex2oat-Aufrufen kann das Gerät jedoch
Arbeitsspeicher, obwohl dies durch Festlegen von dalvik.vm.dex2oat-swap
auf
true
, um die Verwendung einer Auslagerungsdatei zuzulassen. Zu viele Aufrufe können außerdem
unnötigen Kontextwechsel. Sie sollten diese Zahl daher sorgfältig
für jedes Produkt einzeln bewerten.
pm.dexopt.downgrade_after_inactive_days (Standardeinstellung: nicht festgelegt)
Wenn diese Option konfiguriert ist, entfernt ART Service nur Apps, die in den letzten Anzahl der Tage
Wenn nur noch wenig Speicherplatz verfügbar ist, wird während der Hintergrunddexoptimierung der ART-Service aktiviert.
stufen den Compilerfilter von Anwendungen herunter, die in den letzten angegebenen
Anzahl der Tage, um Speicherplatz freizugeben. Der Compiler-Grund hierfür ist inactive
,
und der Compiler-Filter wird durch pm.dexopt.inactive
bestimmt. Der Gruppenbereich
Der Grenzwert zum Auslösen dieser Funktion ist der Grenzwert für wenig Speicherplatz des Speichermanagers
(konfigurierbar über die globalen Einstellungen sys_storage_threshold_percentage
und
sys_storage_threshold_max_bytes
, Standard: 500 MB) plus 500 MB.
Wenn Sie die Liste der Pakete über
ArtManagerLocal#setBatchDexoptStartCallback
, die Pakete in der angegebenen Liste
von BatchDexoptStartCallback
für bg-dexopt
werden nie herabgestuft.
pm.dexopt.disable_bg_dexopt (Standardeinstellung: false)
Dies dient nur zu Testzwecken. ART Service kann den Hintergrund nicht planen. Dexopt des Jobs entfernen.
Wenn der Hintergrund-Dexopt-Job bereits geplant ist, aber noch nicht ausgeführt wurde: hat keine Auswirkung. Das heißt, der Job wird weiterhin ausgeführt.
Eine empfohlene Abfolge von Befehlen, um zu verhindern, dass der Hintergrund-Entfernungsjob ausgeführt wird:
setprop pm.dexopt.disable_bg_dexopt true
pm bg-dexopt-job --disable
Die erste Zeile verhindert, dass der Hintergrunddexopt-Job geplant wird, falls dies noch nicht geplant. Mit der zweiten Zeile wird die Planung des Jobs zum Entfernen des Hintergrunds aufgehoben, wenn und bricht den Hintergrund-Dexopt-Job sofort ab, wenn ausgeführt wird.
ART-Service-APIs
ART Service stellt Java APIs zur Anpassung bereit. Die APIs sind definiert in
ArtManagerLocal
Siehe Javadoc in
art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
für
Nutzungen (Android 14-Quelle, unveröffentlichte Entwicklungsquelle).
ArtManagerLocal
ist ein Singleton, der von LocalManagerRegistry
verwaltet wird. Ein Helfer
Funktion com.android.server.pm.DexOptHelper#getArtManagerLocal
können Sie
erhalten.
import static com.android.server.pm.DexOptHelper.getArtManagerLocal;
Für die meisten APIs ist eine Instanz von PackageManagerLocal.FilteredSnapshot
erforderlich.
das die Informationen zu allen Apps enthält. Rufen Sie dazu einfach
PackageManagerLocal#withFilteredSnapshot
, wobei PackageManagerLocal
ebenfalls
ein Singleton-Paket von LocalManagerRegistry
, das hier erhältlich ist:
com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal
.
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
Im Folgenden sind einige typische Anwendungsfälle für die APIs aufgeführt.
Dexopt für eine App auslösen
Sie können jederzeit Dexopt für jede App auslösen, indem Sie folgenden Befehl aufrufen:
ArtManagerLocal#dexoptPackage
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build());
}
Du kannst auch einen eigenen Deaktivierungsgrund angeben. In diesem Fall werden die Prioritätsklasse Der Compilerfilter muss explizit festgelegt werden.
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder("my-reason")
.setCompilerFilter("speed-profile")
.setPriorityClass(ArtFlags.PRIORITY_BACKGROUND)
.build());
}
Deaktivierung abbrechen
Wenn ein Vorgang durch einen dexoptPackage
-Aufruf initiiert wird, können Sie eine
Abbruchsignal, mit dem Sie den Vorgang an einem bestimmten Punkt abbrechen können. Dies kann
wenn Sie Dexopt asynchron ausführen.
Executor executor = ...; // Your asynchronous executor here.
var cancellationSignal = new CancellationSignal();
executor.execute(() -> {
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build(),
cancellationSignal);
}
});
// When you want to cancel the operation.
cancellationSignal.cancel();
Sie können auch die Hintergrunddexopt-Funktion abbrechen, die vom ART Service initiiert wird.
getArtManagerLocal().cancelBackgroundDexoptJob();
Dexopt-Ergebnisse erhalten
Wenn ein Vorgang durch einen dexoptPackage
-Aufruf initiiert wird, können Sie das Ergebnis abrufen
vom Rückgabewert ab.
DexoptResult result;
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
result = getArtManagerLocal().dexoptPackage(...);
}
// Process the result here.
...
Der ART-Dienst startet auch in vielen Szenarien selbst Dexopt-Vorgänge, z. B.
Hintergrunddexopt. Zum Abhören aller Dexopt-Ergebnisse, unabhängig davon, ob der Vorgang
durch einen dexoptPackage
-Aufruf oder den ART Service initiiert wurde, verwenden Sie
ArtManagerLocal#addDexoptDoneCallback
.
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
// Process the result here.
...
});
Das erste Argument bestimmt, ob nur Aktualisierungen im Ergebnis berücksichtigt werden sollen. Wenn nur Pakete überwachen möchten, die per Dexopt aktualisiert wurden, setzen Sie den Wert auf "true".
Das zweite Argument ist der Executor des Callbacks. Um den Callback auszuführen,
im selben Thread, der dexopt ausführt, Runnable::run
. Wenn Sie das nicht möchten,
-Callback zum Blockieren von Dexopt. Verwenden Sie einen asynchronen Executor.
Sie können mehrere Callbacks hinzufügen, die von ART Service ausgeführt werden sequenziell. Alle Rückrufe bleiben für alle zukünftigen Anrufe aktiv, es sei denn, wenn Sie sie entfernen.
Wenn du einen Callback entfernen möchtest, behalte die Referenz des Callbacks bei, wenn du
fügen Sie sie hinzu und verwenden Sie ArtManagerLocal#removeDexoptDoneCallback
.
DexoptDoneCallback callback = (result) -> {
// Process the result here.
...
};
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */, Runnable::run, callback);
// When you want to remove it.
getArtManagerLocal().removeDexoptDoneCallback(callback);
Paketliste und Dexopt-Parameter anpassen
Der ART-Dienst initiiert selbst Dexopt-Vorgänge während des Starts und im Hintergrund.
Dexopt. Um die Paketliste oder dexopt-Parameter für diese Vorgänge anzupassen,
ArtManagerLocal#setBatchDexoptStartCallback
verwenden.
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
switch (reason) {
case ReasonMapping.REASON_BG_DEXOPT:
var myPackages = new ArrayList<String>(defaultPackages);
myPackages.add(...);
myPackages.remove(...);
myPackages.sort(...);
builder.setPackages(myPackages);
break;
default:
// Ignore unknown reasons.
}
});
Sie können Artikel zur Paketliste hinzufügen, Artikel daraus entfernen, sie sortieren eine ganz andere Liste verwenden.
Unbekannte Gründe müssen von deinem Rückruf ignoriert werden, da weitere Gründe hinzugefügt werden können in in die Zukunft zu führen.
Du kannst maximal ein BatchDexoptStartCallback
festlegen. Der Callback bleibt
für alle zukünftigen Anrufe aktiv, es sei denn, Sie löschen sie.
Wenn du den Callback löschen möchtest, verwende
ArtManagerLocal#clearBatchDexoptStartCallback
getArtManagerLocal().clearBatchDexoptStartCallback();
Parameter des Hintergrund-Dexopt-Jobs anpassen
Standardmäßig wird der Job zur Hintergrunddexopt-Funktion einmal täglich ausgeführt, wenn das Gerät inaktiv ist
und Aufladen. Dies kann geändert werden mit
ArtManagerLocal#setScheduleBackgroundDexoptJobCallback
getArtManagerLocal().setScheduleBackgroundDexoptJobCallback(
Runnable::run,
builder -> {
builder.setPeriodic(TimeUnit.DAYS.toMillis(2));
});
Du kannst maximal ein ScheduleBackgroundDexoptJobCallback
festlegen. Der Callback wird
bleiben für alle zukünftigen Anrufe aktiv, es sei denn, Sie löschen sie.
Wenn du den Callback löschen möchtest, verwende
ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback
getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();
Dexopt vorübergehend deaktivieren
Jeder von ART Service initiierte Dexopt-Vorgang löst ein
BatchDexoptStartCallback
Sie können die Vorgänge weiter abbrechen,
Dexopt effektiv deaktivieren.
Wenn Sie die Hintergrunddexopt-Funktion abbrechen, wird die Standardeinstellung verwendet. Wiederholungsrichtlinie (30 Sekunden, exponentiell, begrenzt auf 5 Stunden).
// Good example.
var shouldDisableDexopt = new AtomicBoolean(false);
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
if (shouldDisableDexopt.get()) {
cancellationSignal.cancel();
}
});
// Disable dexopt.
shouldDisableDexopt.set(true);
getArtManagerLocal().cancelBackgroundDexoptJob();
// Re-enable dexopt.
shouldDisableDexopt.set(false);
Du kannst nur ein BatchDexoptStartCallback
haben. Wenn Sie auch
BatchDexoptStartCallback
zum Anpassen der Paketliste oder zum Entfernen der Parameter
müssen Sie den Code in einem Callback kombinieren.
// Bad example.
// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();
// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();
Die bei der App-Installation durchgeführte Dexoptimierung wird nicht von ART initiiert.
Dienst. Stattdessen wird er vom Paketmanager über ein
dexoptPackage
Anruf. Daher wird sie nicht ausgelöst,
BatchDexoptStartCallback
Um die Deaktivierung bei der App-Installation zu deaktivieren,
Paketmanager kann dexoptPackage
nicht aufrufen.
Compiler-Filter für bestimmte Pakete überschreiben (Android 15 und höher)
Sie können den Compiler-Filter für bestimmte Pakete überschreiben, indem Sie ein
über setAdjustCompilerFilterCallback
zurückrufen. Der Callback wird als
wenn ein Paket entfernt wird, unabhängig davon, ob diese durch
ART-Dienst während des Boot- und Hintergrunddexopts oder durch einen dexoptPackage
-API-Aufruf.
Wenn ein Paket keine Anpassung erfordert, muss der Callback
originalCompilerFilter
getArtManagerLocal().setAdjustCompilerFilterCallback(
Runnable::run,
(packageName, originalCompilerFilter, reason) -> {
if (isVeryImportantPackage(packageName)) {
return "speed-profile";
}
return originalCompilerFilter;
});
Du kannst nur eine AdjustCompilerFilterCallback
festlegen. Wenn Sie
AdjustCompilerFilterCallback
zum Überschreiben des Compiler-Filters für mehrere
Paketen, müssen Sie den Code in einem Callback kombinieren. Der Callback bleibt
für alle zukünftigen Anrufe aktiv, es sei denn, Sie löschen sie.
Wenn du den Callback löschen möchtest, verwende
ArtManagerLocal#clearAdjustCompilerFilterCallback
getArtManagerLocal().clearAdjustCompilerFilterCallback();
Weitere Anpassungen
Der ART-Dienst unterstützt auch einige andere Anpassungen.
Grenzwert zu Temperatur für Hintergrund-Dexopt festlegen
Die Temperaturregelung des Hintergrund-Dexopt-Jobs wird vom Jobplaner durchgeführt.
Der Job wird sofort abgebrochen, wenn die Temperatur erreicht
THERMAL_STATUS_MODERATE
Der Schwellenwert von
THERMAL_STATUS_MODERATE
ist einstellbar.
Bestimmen, ob Hintergrund-Dexopt ausgeführt wird
Der Hintergrund-Dexopt-Job wird vom Jobplaner verwaltet und seine Job-ID ist
27873780
Verwenden Sie Job Scheduler APIs, um festzustellen, ob der Job ausgeführt wird.
// Good example.
var jobScheduler =
Objects.requireNonNull(mContext.getSystemService(JobScheduler.class));
int reason = jobScheduler.getPendingJobReason(27873780);
if (reason == PENDING_JOB_REASON_EXECUTING) {
// Do something when the job is running.
...
}
// Bad example.
var backgroundDexoptRunning = new AtomicBoolean(false);
getArtManagerLocal().setBatchDexoptStartCallback(
Runnable::run,
(snapshot, reason, defaultPackages, builder, cancellationSignal) -> {
if (reason.equals(ReasonMapping.REASON_BG_DEXOPT)) {
backgroundDexoptRunning.set(true);
}
});
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
if (result.getReason().equals(ReasonMapping.REASON_BG_DEXOPT)) {
backgroundDexoptRunning.set(false);
}
});
if (backgroundDexoptRunning.get()) {
// Do something when the job is running.
...
}
Profil für Dexopt angeben
Um die Dexopt-Funktion mithilfe eines Profils zu steuern, platzieren Sie eine .prof
- oder eine .dm
-Datei neben dem
APK
Die Datei .prof
muss eine Profildatei im Binärformat sein und der Dateiname muss
Der Dateiname des APK + .prof
. Beispiel:
base.apk.prof
Der Dateiname der Datei .dm
muss der Name der APK-Datei mit dem Präfix
Erweiterung durch .dm
ersetzt. Beispiel:
base.dm
Um zu überprüfen, ob das Profil zum Entfernen verwendet wird, führen Sie „dexopt“ mit
speed-profile
und prüfen Sie das Ergebnis.
pm art clear-app-profiles <package-name>
pm compile -m speed-profile -f -v <package-name>
Die erste Zeile löscht alle von der Laufzeit erstellten Profile (d.h. die in
/data/misc/profiles
) und prüfen Sie, ob das Profil neben dem APK
das einzige Profil, das ART Service verwenden kann. In der zweiten Zeile wird Dexopt ausgeführt.
mit speed-profile
und übergibt -v
, um das ausführliche Ergebnis auszugeben.
Wenn das Profil bereits verwendet wird, sehen Sie actualCompilerFilter=speed-profile
in
für das Ergebnis. Andernfalls wird actualCompilerFilter=verify
angezeigt. Beispiel:
DexContainerFileDexoptResult{dexContainerFile=/data/app/~~QR0fTV0UbDbIP1Su7XzyPg==/com.google.android.gms-LvusF2uARKOtBbcaPHdUtQ==/base.apk, primaryAbi=true, abi=x86_64, actualCompilerFilter=speed-profile, status=PERFORMED, dex2oatWallTimeMillis=4549, dex2oatCpuTimeMillis=14550, sizeBytes=3715344, sizeBeforeBytes=3715344}
Häufige Gründe, warum ART Service das Profil nicht verwendet, sind:
- Das Profil hat einen falschen Dateinamen oder es befindet sich nicht neben dem APK.
- Das Profil hat das falsche Format.
- Das Profil entspricht nicht dem APK. (Die Prüfsummen im Profil
stimmt mit den Prüfsummen der
.dex
-Dateien im APK überein.)