ART Hizmeti yapılandırması

Başlamadan önce ART Hizmetine ilişkin üst düzey bir genel bakışa bakın.

Android 14'ten başlayarak, uygulamalar için cihazdaki AOT derlemesi (diğer adıyla dexopt) ART Hizmeti tarafından gerçekleştirilir. ART Hizmeti, ART modülünün bir parçasıdır ve bunu 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 destekler:

pm.dexopt.<sebep>

Bu, Dexopt senaryolarında 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 bkz . Derleyici filtreleri .

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.

Prensip olarak ART Hizmeti, mümkün olduğunda tüm uygulamalar için, genellikle arka planda dexopt sırasında profil kılavuzlu derleme ( speed-profile ) yapar. Ancak, diğer uygulamalar tarafından kullanılan bazı uygulamalar vardır ( <uses-library> aracılığıyla veya CONTEXT_INCLUDE_CODE ile Context#createPackageContext kullanılarak dinamik olarak yüklenen). Bu tür uygulamalar gizlilik nedeniyle yerel profilleri kullanamaz.

Böyle bir uygulama için profil rehberli derleme isteniyorsa ART Servisi öncelikle bulut profili kullanmayı dener. Bulut profili yoksa ART Hizmeti pm.dexopt.shared tarafından belirtilen derleyici filtresini kullanır.

İstenen derleme profil kılavuzlu değilse bu özelliğin hiçbir etkisi yoktur.

pm.dexopt.<sebep>.concurrency (varsayılan: 1)

Bu, önceden tanımlanmış belirli derleme nedenlerine yönelik dex2oat çağrılarının sayısıdır ( first-boot , boot-after-ota , boot-after-mainline-update ve bg-dexopt ).

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ı kontrol ederken pm.dexopt.<reason>.concurrency dex2oat çağrısı sayısını kontrol eder. Diğer bir deyişle, 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, maksimum eşzamanlı iş parçacığı sayısına bakılmaksızın (yukarıda tartışılmıştır) her zaman CPU çekirdeği kullanımını sınırlar.

dalvik.vm.*dex2oat-threads ne olursa olsun, tek bir dex2oat çağrısı tüm CPU çekirdeklerini tam olarak kullanmayabilir. Bu nedenle, dex2oat çağrılarının ( pm.dexopt.<reason>.concurrency ) sayısını artırmak, dexopt'un genel ilerlemesini hızlandırmak için CPU çekirdeklerini daha iyi kullanabilir. Bu özellikle önyükleme sırasında kullanışlıdır.

Bununla birlikte, çok fazla dex2oat çağrısına sahip olmak, cihazın belleğinin dolmasına neden olabilir, ancak bu, bir takas dosyasının kullanılmasına izin vermek için dalvik.vm.dex2oat-swap true değerine ayarlanmasıyla azaltılabilir. Çok fazla çağrı aynı zamanda gereksiz içerik değişimine de neden olabilir. Bu nedenle bu sayının ürün bazında dikkatle ayarlanması gerekir.

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 azalmışsa, arka plan dexopt sırasında ART Hizmeti, yer açmak için son belirtilen gün sayısı içinde kullanılmayan uygulamaların derleyici filtresini düşürür. Bunun derleyici nedeninin inactive ve derleyici filtresi pm.dexopt.inactive tarafından belirlenir. Bu özelliği tetiklemek için kullanılan alan eşiği, Depolama Yöneticisinin düşük alan eşiği ( sys_storage_threshold_percentage ve sys_storage_threshold_max_bytes genel ayarları aracılığıyla yapılandırılabilir, varsayılan: 500MB) artı 500MB'dir.

Paket listesini ArtManagerLocal#setBatchDexoptStartCallback aracılığıyla özelleştirirseniz BatchDexoptStartCallback tarafından bg-dexopt için sağlanan listedeki paketlerin sürümü hiçbir zaman düşürülmez.

pm.dexopt.disable_bg_dexopt (varsayılan: yanlış)

Bu yalnızca test amaçlıdır. ART Hizmetinin arka planda dexopt işini planlamasını engeller.

Arka plan dexopt işi zaten planlanmış ancak henüz çalıştırılmamışsa bu seçeneğin hiçbir etkisi yoktur. Yani iş hala devam edecek.

Arka planda dexopt işinin çalışmasını önlemek için önerilen komut dizisi şöyledir:

setprop pm.dexopt.disable_bg_dexopt true
pm bg-dexopt-job --disable

İlk satır, arka plandaki dexopt işinin henüz planlanmamışsa planlanmasını engeller. İkinci satır, eğer zaten planlanmışsa, arka plan dexopt işinin zamanlamasını kaldırır ve eğer çalışıyorsa, arka plan dexopt işini hemen iptal eder.

ART Hizmeti API'leri

ART Hizmeti, özelleştirme için Java API'lerini kullanıma sunar. API'ler ArtManagerLocal tanımlanır. Kullanımlar için art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java adresindeki Javadoc'a bakın ( Android 14 kaynağı , yayınlanmamış geliştirme kaynağı ).

ArtManagerLocal , LocalManagerRegistry tarafından tutulan bir singletondur. Bir yardımcı işlev com.android.server.pm.DexOptHelper#getArtManagerLocal bunu elde etmenize yardımcı olur.

import static com.android.server.pm.DexOptHelper.getArtManagerLocal;

API'lerin çoğu, tüm uygulamaların bilgilerini tutan PackageManagerLocal.FilteredSnapshot örneğini gerektirir. Bunu PackageManagerLocal#withFilteredSnapshot öğesini çağırarak alabilirsiniz; burada PackageManagerLocal aynı zamanda LocalManagerRegistry tarafından tutulan bir tekildir ve com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal adresinden edinilebilir.

import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;

Aşağıda API'lerin bazı tipik kullanım durumları verilmiştir.

Bir uygulama için dexopt'u tetikleyin

ArtManagerLocal#dexoptPackage ç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());
}

Ayrıca kendi dexopt gerekçenizi de iletebilirsiniz. Bunu yaparsanız öncelik sınıfının ve derleyici filtresinin açıkça ayarlanması gerekir.

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'u iptal et

Bir işlem dexoptPackage çağrısıyla başlatılırsa, bir noktada işlemi iptal etmenize olanak tanıyan bir iptal sinyali iletebilirsiniz. Dexopt'u eşzamansız olarak çalıştırdığınızda bu 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 Servisi tarafından başlatılan arka plan dexopt'unu da iptal edebilirsiniz.

getArtManagerLocal().cancelBackgroundDexoptJob();

Dexopt sonuçlarını alın

dexoptPackage çağrısı ile bir işlem başlatılırsa, dönüş değerinden sonucu alabilirsiniz.

DexoptResult result;
try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
  result = getArtManagerLocal().dexoptPackage(...);
}

// Process the result here.
...

ART Hizmeti ayrıca arka planda dexopt gibi birçok senaryoda dexopt işlemlerini kendisi başlatır. İşlem ister bir dexoptPackage çağrısıyla ister 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, sonuca yalnızca güncellemelerin dahil edilip edilmeyeceğini belirler. Yalnızca dexopt tarafından güncellenen paketleri dinlemek istiyorsanız bunu true olarak ayarlayın.

İkinci argüman geri aramanın yürütücüsüdür. Geri aramayı dexopt 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 arama ekleyebilirsiniz ve ART Hizmeti bunların hepsini sırayla yürütecektir. Tüm geri aramalar, siz onları kaldırmadığınız sürece gelecekteki tüm aramalar için etkin kalacaktır.

Bir geri aramayı kaldırmak istiyorsanız, geri aramayı eklediğinizde referansını saklayın ve 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ştirin

ART Hizmeti, önyükleme ve arka plan dexopt sırasında dexopt işlemlerini kendisi başlatır. Bu işlemlere yönelik paket listesini veya dexopt parametrelerini özelleştirmek için 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 öğeler ekleyebilir, öğeleri kaldırabilir, sıralayabilir ve hatta tamamen farklı bir liste kullanabilirsiniz.

Gelecekte daha fazla neden eklenebileceği için geri aramanız bilinmeyen nedenleri göz ardı etmelidir.

En fazla bir BatchDexoptStartCallback ayarlayabilirsiniz. Geri arama, siz silmediğiniz sürece gelecekteki tüm aramalar için etkin kalacaktır.

Geri aramayı temizlemek istiyorsanız ArtManagerLocal#clearBatchDexoptStartCallback kullanın.

getArtManagerLocal().clearBatchDexoptStartCallback();

Arka plan dexopt işinin parametrelerini özelleştirin

Varsayılan olarak arka plan dexopt işi, cihaz boştayken ve şarj olurken günde bir kez çalışır. Bu, 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 kalacaktır.

Geri aramayı temizlemek istiyorsanız ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback kullanın.

getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();

Dexopt'u geçici olarak devre dışı bırak

ART Hizmeti tarafından başlatılan herhangi bir dexopt işlemi 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 ilkesini izler (30 saniye, üstel, 5 saatle sınırlı).

// 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 sahip olabilirsiniz. Paket listesini veya dexopt parametrelerini özelleştirmek için BatchDexoptStartCallback de kullanmak istiyorsanız, kodu tek bir geri çağırmada birleştirmeniz gerekir.

// Bad example.

// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();

// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();

Uygulama kurulumunda gerçekleştirilen dexopt işlemi ART Servisi 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 BatchDexoptStartCallback tetiklemez . Uygulama kurulumunda dexopt'u devre dışı bırakmak için paket yöneticisinin dexoptPackage çağırmasını engelleyin.

Belirli paketler için derleyici filtresini geçersiz kılın (Android 15 (AOSP deneysel)+)

setAdjustCompilerFilterCallback aracılığıyla bir geri çağrı kaydederek belirli paketler için derleyici filtresini geçersiz kılabilirsiniz. Dexopt'un önyükleme ve arka plan dexopt sırasında ART Hizmeti tarafından veya bir dexoptPackage API çağrısı tarafından başlatılmasına bakılmaksızın, bir paketin dexopted'ı yapılacağı zaman geri çağrı çağrılır.

Bir paketin ayarlanması gerekmiyorsa geri aramanın originalCompilerFilter değerini döndürmesi gerekir.

getArtManagerLocal().setAdjustCompilerFilterCallback(
    Runnable::run,
    (packageName, originalCompilerFilter, reason) -> {
      if (isVeryImportantPackage(packageName)) {
        return "speed-profile";
      }
      return originalCompilerFilter;
    });

Yalnızca bir AdjustCompilerFilterCallback ayarlayabilirsiniz. Birden çok paket için derleyici filtresini geçersiz kılmak amacıyla AdjustCompilerFilterCallback kullanmak istiyorsanız, kodu tek bir geri çağırmada birleştirmeniz gerekir. Geri arama, siz silmediğiniz sürece gelecekteki tüm aramalar için etkin kalır.

Geri aramayı temizlemek istiyorsanız ArtManagerLocal#clearAdjustCompilerFilterCallback kullanın.

getArtManagerLocal().clearAdjustCompilerFilterCallback();

Diğer özelleştirmeler

ART Hizmeti ayrıca diğer bazı özelleştirmeleri de destekler.

Arka plan dexopt'u için termal eşiği ayarlayın

Arka plan dexopt işinin termal kontrolü İş Zamanlayıcı tarafından gerçekleştirilir. Sıcaklık THERMAL_STATUS_MODERATE değerine 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 . İşin çalışıp çalışmadığını belirlemek için İş Zamanlayıcı 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 edecek bir profil kullanmak için APK'nın yanına bir .prof dosyası veya .dm dosyası koyun.

.prof dosyası ikili formatta bir profil dosyası olmalı ve dosya adı APK + .prof dosya adı olmalıdır. Örneğin,

base.apk.prof

.dm dosyasının dosya adı, uzantısı .dm ile değiştirilen APK'nın dosya adı olmalıdır. Örneğin,

base.dm

Profilin dexopt için kullanıldığını doğrulamak için 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'nin yanındaki profilin ART Hizmetinin kullanabileceği tek profil olduğundan emin olmak için çalışma zamanı tarafından üretilen tüm profilleri (örneğin, /data/misc/profiles içindekiler) temizler. İkinci satır dexopt'u speed-profile ile çalıştırır ve ayrıntılı sonucu yazdırmak için -v geçer.

Profil kullanılıyorsa sonuçta actualCompilerFilter=speed-profile görürsünüz. Aksi takdirde, actualCompilerFilter=verify 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 Hizmetinin profili kullanmamasının tipik nedenleri arasında aşağıdakiler yer alır:

  • Profilin dosya adı yanlış veya APK'nın yanında değil.
  • Profil yanlış formatta.
  • Profil APK ile eşleşmiyor. (Profildeki sağlama toplamları APK'daki .dex dosyalarının sağlama toplamlarıyla eşleşmiyor.)