Başlamadan önce ART Hizmeti'ne genel bir bakış atın.
Android 14'ten itibaren uygulamalar için cihaz üzerinde AOT derlemesi (diğer adıyla dexopt) ART Hizmeti tarafından işlenir. ART Hizmeti, ART modülünün bir parçasıdır ve sistem özellikleri ile API'ler aracılığıyla özelleştirilebilir.
Sistem özellikleri
ART Hizmeti, ilgili tüm dex2oat seçeneklerini destekler.
Ayrıca, ART Hizmeti aşağıdaki sistem özelliklerini destekler:
pm.dexopt.<reason>
Bu, Dexopt senaryoları bölümünde açıklanan tüm önceden tanımlanmış derleme nedenleri için varsayılan derleyici filtrelerini belirleyen bir dizi sistem özelliğidir.
Daha fazla bilgi için Derleyici filtreleri başlıklı makaleyi inceleyin.
Standart varsayılan değerler şunlardır:
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 (varsayılan: speed)
Bu, diğer uygulamalar tarafından kullanılan uygulamalar için yedek derleyici filtresidir.
ART Hizmeti, mümkün olduğunda (genellikle arka planda dexopt sırasında) tüm uygulamalar için prensip olarak profile dayalı derleme (speed-profile
) yapar. Ancak, diğer uygulamalar tarafından kullanılan (<uses-library>
aracılığıyla veya Context#createPackageContext
ile CONTEXT_INCLUDE_CODE
kullanılarak dinamik olarak yüklenen) bazı uygulamalar vardır. Bu tür uygulamalar, gizlilik nedeniyle yerel profilleri kullanamaz.
Böyle bir uygulama için profile dayalı derleme istenirse ART Hizmeti önce bir bulut profili kullanmayı dener. Bulut profili yoksa ART Hizmeti, pm.dexopt.shared
tarafından belirtilen derleyici filtresini kullanır.
İstenen derleme profile göre yönlendirilmiyorsa bu özelliğin etkisi olmaz.
pm.dexopt.<reason>.concurrency (varsayılan: 1)
Bu, belirli önceden tanımlanmış derleme nedenleri (first-boot
, boot-after-ota
, boot-after-mainline-update
ve bg-dexopt
) için dex2oat çağrılarının sayısıdır.
Bu seçeneğin etkisinin dex2oat kaynak kullanımı seçenekleriyle (dalvik.vm.*dex2oat-threads
, dalvik.vm.*dex2oat-cpu-set
ve görev profilleri) birleştirildiğini unutmayın:
dalvik.vm.*dex2oat-threads
, her dex2oat çağırma işlemi için iş parçacığı sayısını kontrol ederkenpm.dexopt.<reason>.concurrency
, dex2oat çağırma işlemlerinin sayısını kontrol eder. Yani, eşzamanlı ileti dizilerinin maksimum sayısı, iki sistem özelliğinin çarpımıdır.dalvik.vm.*dex2oat-cpu-set
ve görev profilleri, eşzamanlı maksimum iş parçacığı sayısından (yukarıda bahsedilmiştir) bağımsız olarak her zaman CPU çekirdeği kullanımını sınırlar.
Tek bir dex2oat çağrısı, dalvik.vm.*dex2oat-threads
'dan bağımsız olarak tüm CPU çekirdeklerini tam olarak kullanmayabilir. Bu nedenle, dex2oat çağrı sayısını artırmak (pm.dexopt.<reason>.concurrency
), dexopt'un genel ilerleme hızını artırmak için CPU çekirdeklerinden daha iyi yararlanabilir. Bu, özellikle başlatma sırasında yararlıdır.
Ancak, çok fazla dex2oat çağrısı olması, takas dosyası kullanılmasına izin vermek için dalvik.vm.dex2oat-swap
değerinin true
olarak ayarlanmasıyla bu durum hafifletilebilse de cihazın belleğinin tükenmesine neden olabilir. Çok fazla çağırma işlemi de gereksiz bağlam geçişine neden olabilir. Bu nedenle, bu sayı ürün bazında dikkatli bir şekilde ayarlanmalıdır.
pm.dexopt.downgrade_after_inactive_days (varsayılan: ayarlanmadı)
Bu seçenek ayarlanırsa ART Hizmeti yalnızca son belirtilen gün sayısı içinde kullanılan uygulamaları dexopt eder.
Ayrıca, depolama alanı neredeyse dolmuşsa ART Hizmeti, arka planda dexopt sırasında yer açmak için son verilen gün sayısı içinde kullanılmayan uygulamaların derleyici filtresini düşürür. Bunun derleyici nedeni inactive
, derleyici filtresi ise pm.dexopt.inactive
tarafından belirlenir. Bu özelliği tetikleyecek alan eşiği, Depolama Yöneticisi'nin düşük alan eşiği (sys_storage_threshold_percentage
ve sys_storage_threshold_max_bytes
genel ayarları üzerinden yapılandırılabilir, varsayılan: 500 MB) artı 500 MB'tır.
ArtManagerLocal#setBatchDexoptStartCallback
aracılığıyla paket listesini özelleştirirseniz BatchDexoptStartCallback
tarafından bg-dexopt
için sağlanan listedeki paketler hiçbir zaman eski sürüme düşürülmez.
pm.dexopt.disable_bg_dexopt (varsayılan: false)
Bu yalnızca test amaçlıdır. Bu, ART Hizmeti'nin arka planda dexopt işini planlamasını engeller.
Arka plandaki dexopt işi zaten planlanmış ancak henüz çalıştırılmamışsa bu seçeneğin etkisi olmaz. Yani iş yine de çalıştırılır.
Arka plandaki dexopt işinin çalışmasını önlemek için önerilen komut sırası şöyledir:
setprop pm.dexopt.disable_bg_dexopt true
pm bg-dexopt-job --disable
İlk satır, henüz planlanmamışsa arka plandaki dexopt işinin planlanmasını engeller. İkinci satır, arka planda dexopt işi zaten planlanmışsa planını kaldırır ve çalışıyorsa arka planda dexopt işini hemen iptal eder.
ART Service API'leri
ART Hizmeti, özelleştirme için Java API'leri sunar. API'ler ArtManagerLocal
içinde tanımlanır. Kullanım alanları (Android 14 kaynağı, yayınlanmamış geliştirme kaynağı) için art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
bölümündeki Javadoc'a bakın.
ArtManagerLocal
, LocalManagerRegistry
tarafından tutulan bir tekildir. com.android.server.pm.DexOptHelper#getArtManagerLocal
yardımcı işlevi, bu bilgiyi almanıza yardımcı olur.
import static com.android.server.pm.DexOptHelper.getArtManagerLocal;
API'lerin çoğu, tüm uygulamaların bilgilerini içeren bir PackageManagerLocal.FilteredSnapshot
örneği gerektirir. PackageManagerLocal#withFilteredSnapshot
numaralı telefonu arayarak alabilirsiniz. Burada PackageManagerLocal
, LocalManagerRegistry
tarafından tutulan tekil bir öğedir ve com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal
adresinden alınabilir.
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
API'lerin tipik kullanım alanlarından bazıları aşağıda verilmiştir.
Bir uygulama için dexopt'u tetikleme
ArtManagerLocal#dexoptPackage
işlevini çağırarak istediğiniz zaman herhangi bir uygulama için dexopt'u tetikleyebilirsiniz.
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build());
}
Kendi dexopt nedeninizi de iletebilirsiniz. Bu durumda, öncelik sınıfı ve derleyici filtresi açıkça ayarlanmalıdır.
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());
}
Cancel dexopt
Bir işlem dexoptPackage
çağrısıyla başlatılırsa işlemi bir noktada iptal etmenize olanak tanıyan bir iptal sinyali iletebilirsiniz. Bu, dexopt'u eşzamansız olarak çalıştırdığınızda yararlı olabilir.
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();
ART Hizmeti tarafından başlatılan arka planda dexopt işlemini de iptal edebilirsiniz.
getArtManagerLocal().cancelBackgroundDexoptJob();
dexopt sonuçlarını alma
Bir işlem dexoptPackage
çağrısıyla başlatılırsa sonucu dönüş değerinden alabilirsiniz.
DexoptResult result;
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
result = getArtManagerLocal().dexoptPackage(...);
}
// Process the result here.
...
ART Hizmeti, arka planda dexopt gibi birçok senaryoda dexopt işlemlerini kendisi de başlatır. İşlem bir dexoptPackage
çağrısıyla veya ART Hizmeti tarafından başlatılmış olsun, tüm dexopt sonuçlarını dinlemek için ArtManagerLocal#addDexoptDoneCallback
kullanın.
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
// Process the result here.
...
});
İlk bağımsız değişken, sonuçta yalnızca güncellemelerin yer alıp almayacağını belirler. Yalnızca dexopt tarafından güncellenen paketleri dinlemek istiyorsanız true olarak ayarlayın.
İkinci bağımsız değişken, geri çağırma işlevinin yürütücüsüdür. Geri çağırmayı dexopt'u gerçekleştiren aynı iş parçacığında yürütmek için Runnable::run
kullanın. Geri aramanın dexopt'u engellemesini istemiyorsanız eşzamansız bir yürütücü kullanın.
Birden fazla geri çağırma ekleyebilirsiniz ve ART Hizmeti bunların tümünü sırayla yürütür. Kaldırmadığınız sürece tüm geri aramalar, gelecekteki tüm aramalar için etkin kalır.
Bir geri aramayı kaldırmak istiyorsanız geri aramayı eklerken referansını saklayın ve ArtManagerLocal#removeDexoptDoneCallback
simgesini kullanın.
DexoptDoneCallback callback = (result) -> {
// Process the result here.
...
};
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */, Runnable::run, callback);
// When you want to remove it.
getArtManagerLocal().removeDexoptDoneCallback(callback);
Paket listesini ve dexopt parametrelerini özelleştirme
ART Hizmeti, açılış ve arka plan dexopt sırasında dexopt işlemlerini kendisi başlatır. Bu işlemler için paket listesini veya dexopt parametrelerini özelleştirmek istiyorsanız ArtManagerLocal#setBatchDexoptStartCallback
kullanın.
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.
}
});
Paket listesine öğe ekleyebilir, listeden öğe kaldırabilir, listeyi sıralayabilir veya tamamen farklı bir liste kullanabilirsiniz.
Geri arama işleviniz, gelecekte daha fazla neden eklenebileceğinden bilinmeyen nedenleri yoksaymalıdır.
En fazla bir BatchDexoptStartCallback
ayarlayabilirsiniz. Geri arama, temizlemediğiniz sürece gelecekteki tüm aramalar için etkin kalır.
Geri arama işlevini temizlemek istiyorsanız ArtManagerLocal#clearBatchDexoptStartCallback
kullanın.
getArtManagerLocal().clearBatchDexoptStartCallback();
Arka plandaki dexopt işinin parametrelerini özelleştirme
Varsayılan olarak, arka plandaki dexopt işi cihaz boşta ve şarj olurken günde bir kez çalışır. Bu ayar, ArtManagerLocal#setScheduleBackgroundDexoptJobCallback
kullanılarak değiştirilebilir.
getArtManagerLocal().setScheduleBackgroundDexoptJobCallback(
Runnable::run,
builder -> {
builder.setPeriodic(TimeUnit.DAYS.toMillis(2));
});
En fazla bir ScheduleBackgroundDexoptJobCallback
ayarlayabilirsiniz. Geri arama, siz temizlemediğiniz sürece gelecekteki tüm aramalar için etkin kalır.
Geri arama işlevini temizlemek istiyorsanız ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback
kullanın.
getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();
dexopt'u geçici olarak devre dışı bırakma
ART Hizmeti tarafından başlatılan tüm dexopt işlemleri BatchDexoptStartCallback
tetikler. dexopt'u etkili bir şekilde devre dışı bırakmak için işlemleri iptal etmeye devam edebilirsiniz.
İptal ettiğiniz işlem arka planda dexopt ise varsayılan yeniden deneme politikası (30 saniye, üstel, 5 saat ile sınırlı) uygulanır.
// 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);
En fazla bir BatchDexoptStartCallback
olabilir. Paket listesini veya dexopt parametrelerini özelleştirmek için BatchDexoptStartCallback
de kullanmak istiyorsanız kodu tek bir geri çağırma işleminde birleştirmeniz gerekir.
// Bad example.
// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();
// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();
Uygulama yükleme sırasında gerçekleştirilen dexopt işlemi ART
Service tarafından başlatılmaz. Bunun yerine, paket yöneticisi tarafından dexoptPackage
çağrısı aracılığıyla başlatılır. Bu nedenle, tetiklenmez
BatchDexoptStartCallback
. Uygulama yüklenirken dexopt'u devre dışı bırakmak için paket yöneticisinin dexoptPackage
işlevini çağırmasını engelleyin.
Belirli paketler için derleyici filtresini geçersiz kılma (Android 15 ve sonraki sürümler)
setAdjustCompilerFilterCallback
üzerinden geri çağırma işlevi kaydederek belirli paketler için derleyici filtresini geçersiz kılabilirsiniz. Geri çağırma, dexopt işleminin ART Hizmeti tarafından başlatılıp başlatılmadığına bakılmaksızın, bir paket dexopt işlemine tabi tutulacağı her zaman çağrılır. Bu işlem, başlatma ve arka plan dexopt sırasında veya bir dexoptPackage
API çağrısıyla başlatılabilir.
Bir paketin ayarlanması gerekmiyorsa geri çağırma işlevi originalCompilerFilter
değerini döndürmelidir.
getArtManagerLocal().setAdjustCompilerFilterCallback(
Runnable::run,
(packageName, originalCompilerFilter, reason) -> {
if (isVeryImportantPackage(packageName)) {
return "speed-profile";
}
return originalCompilerFilter;
});
Yalnızca bir AdjustCompilerFilterCallback
ayarlayabilirsiniz. Birden fazla paket için derleyici filtresini geçersiz kılmak üzere AdjustCompilerFilterCallback
kullanmak istiyorsanız kodu tek bir geri çağırma işleminde birleştirmeniz gerekir. Geri arama, siz temizlemediğiniz sürece gelecekteki tüm aramalar için etkin kalır.
Geri arama işlevini temizlemek istiyorsanız ArtManagerLocal#clearAdjustCompilerFilterCallback
kullanın.
getArtManagerLocal().clearAdjustCompilerFilterCallback();
Diğer özelleştirmeler
ART Hizmeti, diğer bazı özelleştirmeleri de destekler.
Arka planda dexopt için termal eşiği ayarlama
Arka plandaki dexopt işinin termal kontrolü, İş Planlayıcı tarafından gerçekleştirilir.
Sıcaklık THERMAL_STATUS_MODERATE
'ye ulaştığında iş hemen iptal edilir. THERMAL_STATUS_MODERATE
eşiği ayarlanabilir.
Arka planda dexopt'un çalışıp çalışmadığını belirleme
Arka plan dexopt işi, İş Zamanlayıcı tarafından yönetilir ve iş kimliği 27873780
'dır. İşin çalışıp çalışmadığını belirlemek için Job Scheduler API'lerini kullanın.
// 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.
...
}
dexopt için bir profil sağlama
dexopt'a yol göstermek için profil kullanmak istiyorsanız APK'nın yanına bir .prof
dosyası veya .dm
dosyası yerleştirin.
.prof
dosyası, ikili biçimli bir profil dosyası olmalı ve dosya adı, APK'nın dosya adı + .prof
olmalıdır. Örneğin,
base.apk.prof
.dm
dosyasının adı, uzantısı .dm
ile değiştirilmiş APK'nın dosya adı olmalıdır. Örneğin,
base.dm
Profilin dexopt için kullanıldığını doğrulamak üzere speed-profile
ile dexopt'u çalıştırın ve sonucu kontrol edin.
pm art clear-app-profiles <package-name>
pm compile -m speed-profile -f -v <package-name>
İlk satır, APK'nın yanındaki profilin ART Hizmeti'nin kullanabileceği tek profil olmasını sağlamak için çalışma zamanı tarafından oluşturulan tüm profilleri (varsa /data/misc/profiles
içindekiler) temizler. İkinci satır, speed-profile
ile dexopt'u çalıştırır ve ayrıntılı sonucu yazdırmak için -v
'yi iletir.
Profil kullanılıyorsa sonuçta actualCompilerFilter=speed-profile
simgesi gösterilir. Aksi takdirde actualCompilerFilter=verify
simgesini görürsünüz. Örneğin,
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}
ART Hizmeti'nin profili kullanmamasının tipik nedenleri şunlardır:
- Profilin dosya adı yanlış veya profil, APK'nın yanında değil.
- Profil yanlış biçimde.
- Profil, APK ile eşleşmiyor. (Profildeki sağlama toplamları, APK'daki
.dex
dosyalarının sağlama toplamlarıyla eşleşmiyor.)