ART सेवा का कॉन्फ़िगरेशन

शुरू करने से पहले, ART Service की खास जानकारी देखें.

Android 14 से, ऐप्लिकेशन के लिए उपयोगकर्ता के डिवाइस पर AOT कंपाइलेशन (जिसे dexopt भी कहा जाता है) को ART Service मैनेज करती है. ART Service, ART मॉड्यूल का हिस्सा है. इसे सिस्टम की प्रॉपर्टी और एपीआई की मदद से, अपनी ज़रूरत के हिसाब से बनाया जा सकता है.

सिस्टम की प्रॉपर्टी

ART Service, सभी ज़रूरी dex2oat विकल्पों के साथ काम करती है.

इसके अलावा, ART Service, सिस्टम की इन प्रॉपर्टी के साथ काम करती है:

pm.dexopt.<reason>

यह सिस्टम की प्रॉपर्टी का एक सेट है. इससे, Dexopt के अलग-अलग तरीकों में बताए गए, पहले से तय किए गए सभी कंपाइलेशन की वजहों के लिए, डिफ़ॉल्ट कंपाइलर फ़िल्टर तय किए जाते हैं .

ज़्यादा जानकारी के लिए, कंपाइलर फ़िल्टर देखें.

स्टैंडर्ड डिफ़ॉल्ट वैल्यू ये हैं:

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 (डिफ़ॉल्ट: speed)

यह उन ऐप्लिकेशन के लिए फ़ॉलबैक कंपाइलर फ़िल्टर है जिनका इस्तेमाल दूसरे ऐप्लिकेशन करते हैं.

आम तौर पर, ART Service सभी ऐप्लिकेशन के लिए, प्रोफ़ाइल-गाइडेड कंपाइलेशन (speed-profile) करती है. यह आम तौर पर, बैकग्राउंड dexopt के दौरान होता है. हालांकि, कुछ ऐसे ऐप्लिकेशन होते हैं जिनका इस्तेमाल दूसरे ऐप्लिकेशन करते हैं. ऐसा <uses-library> की मदद से या Context#createPackageContext के साथ CONTEXT_INCLUDE_CODE का इस्तेमाल करके, डाइनैमिक तरीके से लोड करके किया जाता है. निजता से जुड़ी वजहों से, ऐसे ऐप्लिकेशन लोकल प्रोफ़ाइल का इस्तेमाल नहीं कर सकते.

ऐसे ऐप्लिकेशन के लिए, अगर प्रोफ़ाइल-गाइडेड कंपाइलेशन का अनुरोध किया जाता है, तो ART Service सबसे पहले क्लाउड प्रोफ़ाइल का इस्तेमाल करने की कोशिश करती है. अगर क्लाउड प्रोफ़ाइल मौजूद नहीं है, तो ART Service, pm.dexopt.shared में तय किए गए कंपाइलर फ़िल्टर का इस्तेमाल करती है.

अगर अनुरोध किया गया कंपाइलेशन, प्रोफ़ाइल-गाइडेड नहीं है, तो इस प्रॉपर्टी का कोई असर नहीं पड़ता.

pm.dexopt.<reason>.concurrency (डिफ़ॉल्ट: 1)

यह, पहले से तय की गई कंपाइलेशन की कुछ वजहों (first-boot, boot-after-ota, boot-after-mainline-update, और bg-dexopt) के लिए, dex2oat के इनवोकेशन की संख्या है.

ध्यान दें कि इस विकल्प का असर, dex2oat के संसाधन इस्तेमाल करने के विकल्पों (dalvik.vm.*dex2oat-threads, dalvik.vm.*dex2oat-cpu-set, और टास्क प्रोफ़ाइल) के साथ मिलकर होता है:

  • dalvik.vm.*dex2oat-threads से, dex2oat के हर इनवोकेशन के लिए थ्रेड की संख्या कंट्रोल की जाती है. वहीं, pm.dexopt.<reason>.concurrency से, dex2oat के इनवोकेशन की संख्या कंट्रोल की जाती है. इसका मतलब है कि एक साथ चलने वाले थ्रेड की ज़्यादा से ज़्यादा संख्या, सिस्टम की इन दोनों प्रॉपर्टी का गुणनफल होती है.
  • dalvik.vm.*dex2oat-cpu-set और टास्क प्रोफ़ाइल हमेशा सीपीयू कोर के इस्तेमाल को सीमित करती हैं. भले ही, एक साथ चलने वाले थ्रेड की ज़्यादा से ज़्यादा संख्या (ऊपर बताई गई) कुछ भी हो.

dalvik.vm.*dex2oat-threads की वैल्यू कुछ भी हो, dex2oat का एक इनवोकेशन, सीपीयू के सभी कोर का पूरी तरह से इस्तेमाल नहीं कर सकता. इसलिए, dex2oat के इनवोकेशन की संख्या (pm.dexopt.<reason>.concurrency) बढ़ाने से, सीपीयू कोर का बेहतर तरीके से इस्तेमाल किया जा सकता है. इससे, dexopt की पूरी प्रोसेस की स्पीड बढ़ाई जा सकती है. बूट के दौरान, यह खास तौर पर काम आता है.

हालांकि, dex2oat के बहुत ज़्यादा इनवोकेशन होने से, डिवाइस में मेमोरी की कमी हो सकती है. हालांकि, dalvik.vm.dex2oat-swap को true पर सेट करके, स्वैप फ़ाइल का इस्तेमाल करने की अनुमति देकर, इस समस्या को कम किया जा सकता है. बहुत ज़्यादा इनवोकेशन से, कॉन्टेक्स्ट स्विचिंग भी हो सकती है. इसलिए, हर प्रॉडक्ट के लिए, इस संख्या को ध्यान से ट्यून किया जाना चाहिए.

pm.dexopt.downgrade_after_inactive_days (डिफ़ॉल्ट: सेट नहीं है)

अगर यह विकल्प सेट है, तो ART Service सिर्फ़ उन ऐप्लिकेशन के लिए dexopt करती है जिनका इस्तेमाल, पिछले कुछ दिनों में किया गया है.

इसके अलावा, अगर स्टोरेज लगभग खत्म हो गया है, तो बैकग्राउंड dexopt के दौरान, ART Service उन ऐप्लिकेशन के कंपाइलर फ़िल्टर को डाउनग्रेड कर देती है जिनका इस्तेमाल, पिछले कुछ दिनों में नहीं किया गया है. इससे, जगह खाली हो जाती है. इसके लिए, कंपाइलर की वजह inactive होती है. साथ ही, कंपाइलर फ़िल्टर, pm.dexopt.inactive से तय होता है. इस सुविधा को ट्रिगर करने के लिए, स्टोरेज की सीमा, Storage Manager की कम जगह की सीमा (ग्लोबल सेटिंग sys_storage_threshold_percentage और sys_storage_threshold_max_bytes के ज़रिए कॉन्फ़िगर की जा सकती है, डिफ़ॉल्ट: 500 MB) के साथ-साथ 500 MB होती है.

अगर पैकेज की सूची को अपनी ज़रूरत के हिसाब से बनाया जाता है ArtManagerLocal#setBatchDexoptStartCallback, तो से मिली सूची में मौजूद पैकेज BatchDexoptStartCallback के लिए bg-dexopt कभी भी डाउनग्रेड नहीं किए जाते.

pm.dexopt.disable_bg_dexopt (डिफ़ॉल्ट: false)

यह सिर्फ़ टेस्टिंग के लिए है. इससे, ART Service को बैकग्राउंड dexopt का काम शेड्यूल करने से रोका जा सकता है.

अगर बैकग्राउंड dexopt का काम पहले से शेड्यूल है, लेकिन अभी तक नहीं हुआ है, तो इस विकल्प का कोई असर नहीं पड़ता. इसका मतलब है कि काम अब भी होगा.

बैकग्राउंड dexopt का काम रोकने के लिए, कमांड का यह क्रम इस्तेमाल करने का सुझाव दिया जाता है:

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

पहली लाइन से, बैकग्राउंड dexopt का काम शेड्यूल होने से रोका जा सकता है. हालांकि, यह तब काम करता है, जब काम शेड्यूल न किया गया हो. दूसरी लाइन से, बैकग्राउंड dexopt का काम अनशेड्यूल किया जा सकता है. हालांकि, यह तब काम करता है, जब काम पहले से शेड्यूल हो. इसके अलावा, अगर काम चल रहा है, तो यह उसे तुरंत रद्द कर देता है.

ART Service के एपीआई

ART Service, अपनी ज़रूरत के हिसाब से बदलाव करने के लिए, Java API उपलब्ध कराती है. ये एपीआई, ArtManagerLocal में तय किए गए हैं. इनके इस्तेमाल के बारे में जानने के लिए, art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java में मौजूद Javadoc देखें. यह Android 14 का सोर्स है. साथ ही, इसमें डेवलपमेंट का ऐसा सोर्स भी शामिल है जिसे अभी रिलीज़ नहीं किया गया है.

ArtManagerLocal, LocalManagerRegistry में मौजूद एक सिंगलटन है. com.android.server.pm.DexOptHelper#getArtManagerLocal नाम का हेल्पर फ़ंक्शन, इसे पाने में आपकी मदद करता है.

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

ज़्यादातर एपीआई के लिए, PackageManagerLocal.FilteredSnapshot के इंस्टेंस की ज़रूरत होती है. इसमें सभी ऐप्लिकेशन की जानकारी होती है. इसे PackageManagerLocal#withFilteredSnapshot को कॉल करके पाया जा सकता है. यहां PackageManagerLocal भी LocalManagerRegistry में मौजूद एक सिंगलटन है. इसे com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal से पाया जा सकता है.

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

यहां एपीआई के इस्तेमाल के कुछ सामान्य उदाहरण दिए गए हैं.

किसी ऐप्लिकेशन के लिए dexopt को ट्रिगर करना

ArtManagerLocal#dexoptPackage को कॉल करके, किसी भी ऐप्लिकेशन के लिए dexopt को किसी भी समय ट्रिगर किया जा सकता है.

try (var snapshot = getPackageManagerLocal().withFilteredSnapshot()) {
  getArtManagerLocal().dexoptPackage(
      snapshot,
      "com.google.android.calculator",
      new DexoptParams.Builder(ReasonMapping.REASON_INSTALL).build());
}

आपके पास dexopt की वजह भी पास करने का विकल्प होता है. अगर ऐसा किया जाता है, तो प्राथमिकता वाली क्लास और कंपाइलर फ़िल्टर को साफ़ तौर पर सेट करना होगा.

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 रद्द करना

अगर कोई कार्रवाई, dexoptPackage कॉल से शुरू की जाती है, तो रद्द करने का सिग्नल पास किया जा सकता है. इससे, किसी भी समय कार्रवाई रद्द की जा सकती है. यह तब काम आ सकता है, जब dexopt को एसिंक्रोनस तरीके से चलाया जाता है.

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 Service से शुरू किए गए बैकग्राउंड dexopt को भी रद्द किया जा सकता है.

getArtManagerLocal().cancelBackgroundDexoptJob();

dexopt के नतीजे पाना

अगर कोई कार्रवाई, dexoptPackage कॉल से शुरू की जाती है, तो रिटर्न वैल्यू से नतीजा पाया जा सकता है.

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

// Process the result here.
...

ART Service, कई स्थितियों में dexopt की कार्रवाइयां खुद शुरू करती है. जैसे, बैकग्राउंड dexopt. dexopt के सभी नतीजे सुनने के लिए, चाहे कार्रवाई dexoptPackage कॉल से शुरू की गई हो या ART Service से, ArtManagerLocal#addDexoptDoneCallback का इस्तेमाल करें.

getArtManagerLocal().addDexoptDoneCallback(
    false /* onlyIncludeUpdates */,
    Runnable::run,
    (result) -> {
      // Process the result here.
      ...
    });

पहले आर्ग्युमेंट से तय होता है कि नतीजे में सिर्फ़ अपडेट शामिल करने हैं या नहीं. अगर आपको सिर्फ़ उन पैकेज के बारे में सुनना है जिन्हें dexopt से अपडेट किया गया है, तो इसे 'सही' पर सेट करें.

दूसरा आर्ग्युमेंट, कॉलबैक का एक्ज़ीक्यूटर है. dexopt करने वाले उसी थ्रेड पर कॉलबैक को चलाने के लिए, Runnable::run का इस्तेमाल करें. अगर आपको कॉलबैक से dexopt को ब्लॉक नहीं करना है, तो एसिंक्रोनस एक्ज़ीक्यूटर का इस्तेमाल करें.

एक से ज़्यादा कॉलबैक जोड़े जा सकते हैं. ART Service, उन सभी को क्रम से चलाएगी. जब तक कॉलबैक नहीं हटाए जाते, तब तक वे आने वाले समय में किए जाने वाले सभी कॉल के लिए चालू रहेंगे.

अगर आपको कोई कॉलबैक हटाना है, तो उसे जोड़ते समय उसका रेफ़रंस सेव करें. इसके बाद, 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);

पैकेज की सूची और dexopt के पैरामीटर को अपनी ज़रूरत के हिसाब से बनाना

ART Service, बूट और बैकग्राउंड dexopt के दौरान, dexopt की कार्रवाइयां खुद शुरू करती है. उन कार्रवाइयों के लिए, पैकेज की सूची या dexopt के पैरामीटर को अपनी ज़रूरत के हिसाब से बनाने के लिए, ArtManagerLocal#setBatchDexoptStartCallback का इस्तेमाल करें.

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.
      }
    });

पैकेज की सूची में आइटम जोड़े जा सकते हैं, उनसे आइटम हटाए जा सकते हैं, उन्हें क्रम से लगाया जा सकता है या पूरी तरह से अलग सूची का इस्तेमाल भी किया जा सकता है.

आपके कॉलबैक को, कंपाइलेशन की अज्ञात वजहों को अनदेखा करना होगा, क्योंकि आने वाले समय में और वजहें जोड़ी जा सकती हैं.

ज़्यादा से ज़्यादा एक BatchDexoptStartCallback सेट किया जा सकता है. जब तक कॉलबैक को साफ़ नहीं किया जाता, तब तक वह आने वाले समय में किए जाने वाले सभी कॉल के लिए चालू रहेगा.

अगर आपको कॉलबैक को साफ़ करना है, तो ArtManagerLocal#clearBatchDexoptStartCallback का इस्तेमाल करें.

getArtManagerLocal().clearBatchDexoptStartCallback();

बैकग्राउंड dexopt के काम के पैरामीटर को अपनी ज़रूरत के हिसाब से बनाना

डिफ़ॉल्ट रूप से, बैकग्राउंड dexopt का काम दिन में एक बार तब होता है, जब डिवाइस इस्तेमाल में न हो और चार्ज हो रहा हो. ArtManagerLocal#setScheduleBackgroundDexoptJobCallback का इस्तेमाल करके, इसे बदला जा सकता है.

getArtManagerLocal().setScheduleBackgroundDexoptJobCallback(
    Runnable::run,
    builder -> {
      builder.setPeriodic(TimeUnit.DAYS.toMillis(2));
    });

ज़्यादा से ज़्यादा एक ScheduleBackgroundDexoptJobCallback सेट किया जा सकता है. जब तक कॉलबैक को साफ़ नहीं किया जाता, तब तक वह आने वाले समय में किए जाने वाले सभी कॉल के लिए चालू रहेगा.

अगर आपको कॉलबैक को साफ़ करना है, तो ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback का इस्तेमाल करें.

getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();

dexopt को कुछ समय के लिए बंद करना

ART Service से शुरू की गई dexopt की किसी भी कार्रवाई से, BatchDexoptStartCallback ट्रिगर होता है. dexopt को पूरी तरह से बंद करने के लिए, कार्रवाइयों को रद्द किया जा सकता है.

अगर रद्द की गई कार्रवाई, बैकग्राउंड dexopt है, तो यह फिर से करने की डिफ़ॉल्ट नीति (30 सेकंड, एक्स्पोनेंशियल, ज़्यादा से ज़्यादा पांच घंटे) के मुताबिक होती है.

// 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);

ज़्यादा से ज़्यादा एक BatchDexoptStartCallback सेट किया जा सकता है. अगर आपको पैकेज की सूची या dexopt के पैरामीटर को अपनी ज़रूरत के हिसाब से बनाने के लिए, BatchDexoptStartCallback का इस्तेमाल भी करना है, तो आपको कोड को एक कॉलबैक में जोड़ना होगा.

// Bad example.

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

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

ऐप्लिकेशन इंस्टॉल करने पर किया गया dexopt का काम, ART Service से शुरू नहीं होता. इसके बजाय, यह काम, पैकेज मैनेजर से dexoptPackage कॉल के ज़रिए शुरू होता है. इसलिए, इससे BatchDexoptStartCallback ट्रिगर नहीं होता. ऐप्लिकेशन इंस्टॉल करने पर dexopt को बंद करने के लिए, पैकेज मैनेजर को dexoptPackage कॉल करने से रोकें.

चुनिंदा पैकेज के लिए कंपाइलर फ़िल्टर को बदलना (Android 15 और उसके बाद के वर्शन)

setAdjustCompilerFilterCallback के ज़रिए कॉलबैक रजिस्टर करके, चुनिंदा पैकेज के लिए कंपाइलर फ़िल्टर को बदला जा सकता है. जब भी किसी पैकेज के लिए dexopt किया जाता है, तब कॉलबैक को कॉल किया जाता है. इससे कोई फ़र्क़ नहीं पड़ता कि dexopt, ART Service से बूट और बैकग्राउंड dexopt के दौरान शुरू किया गया है या dexoptPackage एपीआई कॉल से.

अगर किसी पैकेज में बदलाव करने की ज़रूरत नहीं है, तो कॉलबैक को originalCompilerFilter लौटाना होगा.

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

सिर्फ़ एक AdjustCompilerFilterCallback सेट किया जा सकता है. अगर आपको एक से ज़्यादा पैकेज के लिए कंपाइलर फ़िल्टर को बदलने के लिए, AdjustCompilerFilterCallback का इस्तेमाल करना है, तो आपको कोड को एक कॉलबैक में जोड़ना होगा. जब तक कॉलबैक को साफ़ नहीं किया जाता, तब तक वह आने वाले समय में किए जाने वाले सभी कॉल के लिए चालू रहेगा.

अगर आपको कॉलबैक को साफ़ करना है, तो ArtManagerLocal#clearAdjustCompilerFilterCallback का इस्तेमाल करें.

getArtManagerLocal().clearAdjustCompilerFilterCallback();

अन्य बदलाव

ART Service, कुछ अन्य बदलावों के साथ भी काम करती है.

बैकग्राउंड dexopt के लिए थर्मल थ्रेशोल्ड सेट करना

बैकग्राउंड dexopt के काम का थर्मल कंट्रोल, Job Scheduler करता है. जब तापमान THERMAL_STATUS_MODERATE पर पहुंच जाता है, तो काम तुरंत रद्द हो जाता है. THERMAL_STATUS_MODERATE का थ्रेशोल्ड, ट्यून किया जा सकता है.

यह पता लगाना कि बैकग्राउंड dexopt चल रहा है या नहीं

बैकग्राउंड dexopt के काम को Job Scheduler मैनेज करता है. इसका जॉब आईडी 27873780 है. यह पता लगाने के लिए कि काम चल रहा है या नहीं, Job Scheduler के एपीआई का इस्तेमाल करें.

// 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 के लिए प्रोफ़ाइल उपलब्ध कराना

dexopt को गाइड करने के लिए, प्रोफ़ाइल का इस्तेमाल करने के लिए, एपीके के बगल में .prof फ़ाइल या .dm फ़ाइल रखें.

.prof फ़ाइल, बाइनरी-फ़ॉर्मैट वाली प्रोफ़ाइल फ़ाइल होनी चाहिए. साथ ही, फ़ाइल का नाम, एपीके के फ़ाइल नाम के साथ .prof होना चाहिए. उदाहरण के लिए,

base.apk.prof

.dm फ़ाइल का नाम, एपीके के फ़ाइल नाम के साथ एक्सटेंशन की जगह .dm होना चाहिए. उदाहरण के लिए,

base.dm

यह पुष्टि करने के लिए कि dexopt के लिए प्रोफ़ाइल का इस्तेमाल किया जा रहा है, speed-profile के साथ dexopt चलाएं और नतीजा देखें.

pm art clear-app-profiles <package-name>
pm compile -m speed-profile -f -v <package-name>

पहली लाइन, रनटाइम से जनरेट की गई सभी प्रोफ़ाइल (यानी, /data/misc/profiles में मौजूद प्रोफ़ाइल) को मिटा देती है. ऐसा इसलिए किया जाता है, ताकि यह पक्का किया जा सके कि एपीके के बगल में मौजूद प्रोफ़ाइल ही वह प्रोफ़ाइल है जिसका इस्तेमाल ART Service कर सकती है. दूसरी लाइन, speed-profile के साथ dexopt चलाती है. साथ ही, यह वर्बोस नतीजा प्रिंट करने के लिए -v पास करती है.

अगर प्रोफ़ाइल का इस्तेमाल किया जा रहा है, तो नतीजे में actualCompilerFilter=speed-profile दिखता है. ऐसा न होने पर, actualCompilerFilter=verify दिखता है. उदाहरण के लिए,

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 Service, प्रोफ़ाइल का इस्तेमाल क्यों नहीं करती, इसकी सामान्य वजहें ये हैं:

  • प्रोफ़ाइल का फ़ाइल नाम गलत है या यह एपीके के बगल में नहीं है.
  • प्रोफ़ाइल गलत फ़ॉर्मैट में है.
  • प्रोफ़ाइल, एपीके से मेल नहीं खाती. (प्रोफ़ाइल में मौजूद चेकसम, एपीके में मौजूद .dex फ़ाइलों के चेकसम से मेल नहीं खाते.)