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 yönetilir. ART Hizmeti, ART modülünün bir parçasıdır. Bu hizmeti, sistem özellikleri ve API'ler aracılığıyla özelleştirebilirsiniz.
Sistem özellikleri
ART Hizmeti, tüm ilgili dex2oat seçeneklerini destekler.
Ayrıca, ART Hizmeti aşağıdaki sistem özelliklerini de destekler:
pm.dexopt.<reason>
Bu, Dexopt senaryolarında açıklanan tüm önceden tanımlanmış derleme nedenleri için varsayılan derleyici filtrelerini belirleyen bir sistem özellikleri grubudur.
Daha fazla bilgi için Derleyici filtreleri bölümüne bakın.
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: hız)
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 profil yönlendirmeli derleme (speed-profile
) yapar. Bununla birlikte, diğer uygulamalar tarafından kullanılan (<uses-library>
aracılığıyla veya CONTEXT_INCLUDE_CODE
ile Context#createPackageContext
kullanılarak dinamik olarak yüklenen) bazı uygulamalar vardır. Bu tür uygulamalar, gizlilik nedeniyle yerel profilleri kullanamaz.
Bu tür bir uygulama için profil yönlendirmeli 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 profil odaklı değilse bu özelliğin hiçbir 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ğrısı için iş parçacığı sayısını,pm.dexopt.<reason>.concurrency
ise dex2oat çağrılarının sayısını kontrol eder. Yani maksimum eşzamanlı iş parçacığı sayısı, iki sistem özelliğinin çarpımıdır.dalvik.vm.*dex2oat-cpu-set
ve görev profilleri, eşzamanlı maksimum ileti dizisi sayısından (yukarıda ele alınmıştır) bağımsız olarak her zaman CPU çekirdek kullanımını sınırlandırır.
Tek bir dex2oat çağrısı, dalvik.vm.*dex2oat-threads
'ten bağımsız olarak tüm CPU çekirdeklerini tam olarak kullanamayabilir. Bu nedenle, dex2oat çağrılarının sayısını (pm.dexopt.<reason>.concurrency
) artırmak, CPU çekirdeklerini daha iyi kullanabilir ve dexopt'in genel ilerleme hızını artırabilir. Bu, özellikle önyükleme sırasında yararlıdır.
Bununla birlikte, çok fazla dex2oat çağrısı olması, değişim dosyasının kullanılmasına izin vermek için dalvik.vm.dex2oat-swap
politikasını true
değerine ayarlamakla cihazın belleğin bitmesine neden olabilir. Çok fazla çağrı, gereksiz bağlam
geçişine de neden olabilir. Bu nedenle, bu sayı ürüne göre dikkatlice 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'tan çıkarır.
Ayrıca, depolama alanı neredeyse doluysa ART Hizmeti, arka planda dexopt işlemi sırasında yer açmak için son belirtilen 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 tetikleyen 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'dır.
Paket listesini ArtManagerLocal#setBatchDexoptStartCallback
aracılığıyla özelleştirirseniz bg-dexopt
için BatchDexoptStartCallback
tarafından sağlanan listedeki paketler hiçbir zaman eski sürüme geçirilmez.
pm.dexopt.disable_bg_dexopt (varsayılan: false)
Bu yalnızca test amaçlıdır. ART Hizmeti'nin arka planda dexopt işini planlamasını engeller.
Arka planda dexopt işi zaten planlanmışsa ancak henüz çalıştırılmamışsa bu seçeneğin hiçbir etkisi olmaz. Yani iş çalışmaya devam eder.
Arka planda dexopt işinin çalışmasını önlemek için önerilen komut dizisi:
setprop pm.dexopt.disable_bg_dexopt true
pm bg-dexopt-job --disable
İlk satır, henüz planlanmamışsa arka planda dexopt işinin planlanmasını engeller. İkinci satır, önceden planlanmışsa arka planda dexopt işinin planlamasını iptal eder ve çalışıyorsa arka planda dexopt işini hemen iptal eder.
ART Hizmet API'leri
ART Hizmeti, özelleştirme için Java API'lerini gösterir. API'ler ArtManagerLocal
adresinde tanımlanır. Kullanım alanları için art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
içindeki Javadoc'a bakın (Android 14 kaynağı, yayınlanmamış geliştirme kaynağı).
ArtManagerLocal
, LocalManagerRegistry
tarafından tutulan tekil bir öğedir. com.android.server.pm.DexOptHelper#getArtManagerLocal
yardımcı işlevi, bu değeri elde etmenize 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
çağrısı yaparak bu değeri alabilirsiniz. Burada PackageManagerLocal
, LocalManagerRegistry
tarafından tutulan ve com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal
'dan alınabilen tekil bir değerdir.
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
Aşağıda, API'lerin bazı tipik kullanım alanları verilmiştir.
Bir uygulama için dexopt'i tetikleme
ArtManagerLocal#dexoptPackage
çağırarak istediğiniz zaman herhangi bir uygulama için dexopt'yi tetikleyebilirsiniz.
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
getArtManagerLocal().dexoptPackage(
snapshot,
"com.google.android.calculator",
new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build());
}
Ayrıca kendi dexopt nedeninizi de iletebilirsiniz. Bunu yaparsanız öncelik sınıfı ve derleyici filtresi açık bir şekilde 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());
}
Dexopt'yi iptal et
Bir işlem dexoptPackage
çağrısıyla başlatılırsa iptal sinyali iletebilir ve böylece işlemi bir noktada iptal edebilirsiniz. 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();
Ayrıca, ART Hizmeti tarafından başlatılan arka plan devre dışı bırakma 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öndürülen değerden alabilirsiniz.
DexoptResult result;
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
result = getArtManagerLocal().dexoptPackage(...);
}
// Process the result here.
...
ART Hizmeti, arka planda dexopt işlemi gibi birçok senaryoda dexopt işlemlerini kendisi de başlatır. İşlemin bir dexoptPackage
çağrısı veya ART Hizmeti tarafından başlatılmış olması fark etmeksizin, tüm kaldırma sonuçlarını dinlemek için ArtManagerLocal#addDexoptDoneCallback
işlevini kullanın.
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
// Process the result here.
...
});
İlk bağımsız değişken, sonuca yalnızca güncellemelerin dahil edilip edilmeyeceğini belirler. Yalnızca dexopt tarafından güncellenen paketleri dinlemek istiyorsanız bu değeri 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 işlemi gerçekleştiren aynı iş parçacığında yürütmek için Runnable::run
işlevini kullanın. Geri çağırmanın dexopt'yi engellemesini istemiyorsanız eşzamansız bir yürütücü kullanın.
Birden fazla geri çağırma ekleyebilirsiniz. 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 çağırmayı kaldırmak isterseniz geri arama referansını eklerken ArtManagerLocal#removeDexoptDoneCallback
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, önyükleme ve arka planda dexopt sırasında dexopt işlemlerini kendisi başlatır. Bu işlemler için paket listesini veya dexopt parametrelerini özelleştirmek üzere ArtManagerLocal#setBatchDexoptStartCallback
simgesini 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.
Gelecekte daha fazla neden eklenebilir. Bu nedenle, geri arama işleminizde bilinmeyen nedenler yoksayılmalıdır.
En fazla bir BatchDexoptStartCallback
ayarlayabilirsiniz. Geri çağırma, silmediğiniz sürece gelecekteki tüm aramalar için etkin kalır.
Geri aramayı silmek için ArtManagerLocal#clearBatchDexoptStartCallback
simgesini kullanın.
getArtManagerLocal().clearBatchDexoptStartCallback();
Arka planda dexopt işinin parametrelerini özelleştirme
Varsayılan olarak, arka plan kaldırma 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 silmediğiniz sürece gelecekteki tüm aramalar için etkin kalır.
Geri çağırmayı temizlemek isterseniz ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback
işlevini 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 bir 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 saatle sınırlı) geçerli olur.
// 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
'ünüz olabilir. Paket listesini veya dexopt parametrelerini özelleştirmek için BatchDexoptStartCallback
'ü de kullanmak istiyorsanız kodu tek bir geri çağırma işlevinde birleştirmeniz gerekir.
// Bad example.
// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();
// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();
Uygulama yüklemesinde gerçekleştirilen dexopt işlemi, ART Hizmeti tarafından başlatılmaz. Bunun yerine, paket yöneticisi tarafından bir dexoptPackage
çağrısı aracılığıyla başlatılır. Bu nedenle, BatchDexoptStartCallback
tetiklenmez. Uygulama yükleme sırasında dexopt'u devre dışı bırakmak için paket yöneticisinin dexoptPackage
çağrısını engelleyin.
Belirli paketler için derleyici filtresini geçersiz kılma (Android 15 ve sonraki sürümler)
setAdjustCompilerFilterCallback
aracılığıyla geri çağırma işlevi kaydederek belirli paketler için derleyici filtresini geçersiz kılabilirsiniz. Geri çağırma işlevi, bir paketin dexopt işlemine tabi tutulacağı her zaman çağrılır. Bu çağrı, dexopt işleminin ART Hizmeti tarafından önyükleme ve arka plan dexopt işlemi sırasında mı yoksa bir dexoptPackage
API çağrısı tarafından mı başlatıldığına bakılmaksızın gerçekleşir.
Bir paketin ayarlanması gerekmiyorsa geri çağırma işlevi originalCompilerFilter
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şlevinde birleştirmeniz gerekir. Geri çağırma, silmediğiniz sürece gelecekteki tüm çağrılar için etkin kalır.
Geri aramayı silmek için ArtManagerLocal#clearAdjustCompilerFilterCallback
simgesini 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 plan dexopt işinin termal kontrolü, İş Planlayıcı tarafından gerçekleştirilir.
Sıcaklık THERMAL_STATUS_MODERATE
'e 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 planda dexopt işi İş Planlayıcı tarafından yönetilir ve iş kimliği 27873780
'tü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ğlayın
Dexopt'a rehberlik etmek için bir profil kullanmak istiyorsanız APK'nın yanına bir .prof
dosyası veya .dm
dosyası ekleyin.
.prof
dosyası ikili biçimli bir profil dosyası olmalı ve dosya adı, APK dosya adının .prof
ile birlikte yazılmış halidir. Örneğin,
base.apk.prof
.dm
dosyasının adı, uzantısı .dm
ile değiştirilmiş APK dosyasının adıdır. Örneğin,
base.dm
Profilin dexopt için kullanıldığını doğrulamak üzere dexopt'u speed-profile
ile ç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 Service'in kullanabileceği tek profil olduğundan emin olmak için çalışma zamanı tarafından oluşturulan tüm profilleri (/data/misc/profiles
içinde olanlar) temizler. İkinci satır, dexopt'u speed-profile
ile çalıştırır ve ayrıntılı sonucu yazdırmak için -v
parametresini iletir.
Profil kullanılıyorsa sonuçta actualCompilerFilter=speed-profile
simgesi gösterilir. Aksi durumda actualCompilerFilter=verify
gösterilir. Ö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 hizmetinin profili kullanmamasının yaygın nedenleri şunlardır:
- Profilin dosya adı yanlış veya APK'nın yanında değil.
- Profilin biçimi yanlış.
- Profil, APK ile eşleşmiyor. (Profildeki sağlamalar, APK'daki
.dex
dosyalarının sağlamalarıyla eşleşmiyor.)