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

शुरू करने से पहले, एआरटी सेवा की खास जानकारी देखें.

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

अगर ऐसे ऐप्लिकेशन के लिए, प्रोफ़ाइल के हिसाब से कंपाइल करने का अनुरोध किया जाता है, तो 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 invocatio के लिए थ्रेड की संख्या को कंट्रोल करता है, जबकि pm.dexopt.<reason>.concurrency, dex2oat invocatio की संख्या को कंट्रोल करता है. इसका मतलब है कि एक साथ चलने वाली थ्रेड की ज़्यादा से ज़्यादा संख्या, दोनों सिस्टम प्रॉपर्टी का गुणनफल होती है.
  • 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 करने के दौरान, ART Service, उन ऐप्लिकेशन के कंपाइलर फ़िल्टर को डाउनग्रेड कर देती है जिनका इस्तेमाल पिछले कुछ दिनों में नहीं किया गया है. इससे स्टोरेज खाली हो जाता है. इसके लिए कंपाइलर की वजह inactive है और कंपाइलर फ़िल्टर pm.dexopt.inactive से तय होता है. इस सुविधा को ट्रिगर करने के लिए, स्टोरेज मैनेजर में स्टोरेज का कम होने का थ्रेशोल्ड (ग्लोबल सेटिंग sys_storage_threshold_percentage और sys_storage_threshold_max_bytes की मदद से कॉन्फ़िगर किया जा सकता है, डिफ़ॉल्ट: 500 एमबी) और 500 एमबी जोड़ें.

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

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

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

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

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

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

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

ART Service APIs

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

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

बैकग्राउंड में dexopt की प्रोसेस को भी रद्द किया जा सकता है. यह प्रोसेस, ART Service शुरू करती है.

getArtManagerLocal().cancelBackgroundDexoptJob();

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

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

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

// Process the result here.
...

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

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 सेकंड, एक्सपोनेंशियल, 5 घंटे तक) का पालन करता है.

// 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 के ज़रिए कॉलबैक रजिस्टर करके, कुछ पैकेज के लिए कंपाइलर फ़िल्टर को बदला जा सकता है. जब भी किसी पैकेज को डीकोड किया जाता है, तब इस कॉलबैक को कॉल किया जाता है. भले ही, डीकोड करने की प्रोसेस को ART Service ने बूट और बैकग्राउंड डीकोड करने के दौरान शुरू किया हो या dexoptPackage API कॉल से.

अगर किसी पैकेज में बदलाव की ज़रूरत नहीं है, तो कॉलबैक को 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 जॉब के थर्मल कंट्रोल को, जॉब शेड्यूलर करता है. तापमान THERMAL_STATUS_MODERATE तक पहुंचने पर, टास्क तुरंत रद्द हो जाता है. THERMAL_STATUS_MODERATE के थ्रेशोल्ड को बदला जा सकता है.

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

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

// 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 को गाइड करने के लिए प्रोफ़ाइल का इस्तेमाल करने के लिए, APK के बगल में .prof फ़ाइल या .dm फ़ाइल डालें.

.prof फ़ाइल, बाइनरी फ़ॉर्मैट वाली प्रोफ़ाइल फ़ाइल होनी चाहिए. साथ ही, फ़ाइल का नाम, APK + .prof का फ़ाइल नाम होना चाहिए. जैसे, मुझे पता चला कि

base.apk.prof

.dm फ़ाइल का नाम, APK फ़ाइल का नाम होना चाहिए. साथ ही, एक्सटेंशन को .dm से बदला जाना चाहिए. जैसे, मुझे पता चला कि

base.dm

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

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

पहली लाइन, रनटाइम से जनरेट की गई सभी प्रोफ़ाइलों को मिटा देती है.अगर कोई प्रोफ़ाइल है, तो उसे भी मिटा देती है. ऐसा इसलिए किया जाता है, ताकि यह पक्का किया जा सके कि APK के बगल में मौजूद प्रोफ़ाइल ही ऐसी प्रोफ़ाइल हो जिसका इस्तेमाल ART सेवा कर सके./data/misc/profiles दूसरी लाइन, 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, प्रोफ़ाइल का इस्तेमाल न करने की ये वजहें हो सकती हैं:

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