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

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

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

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

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

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

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

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

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

pm.dexopt.<reason>.concurrency (default: 1)

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

ध्यान दें कि इस विकल्प का असर, 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 और टास्क प्रोफ़ाइलें, सीपीयू कोर के इस्तेमाल को हमेशा सीमित करती हैं. भले ही, एक साथ चलने वाले थ्रेड की ज़्यादा से ज़्यादा संख्या कितनी भी हो (इसके बारे में ऊपर बताया गया है).

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

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

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

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

इसके अलावा, अगर स्टोरेज लगभग खत्म हो गया है, तो बैकग्राउंड में 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 (डिफ़ॉल्ट: false)

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

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

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

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

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

ART Service API

ART सेवा, कस्टमाइज़ेशन के लिए 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#withFilteredSnapshot, LocalManagerRegistry के पास मौजूद एक सिंगलटन भी है. इसे com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal से पाया जा सकता है.PackageManagerLocal

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 सेवा शुरू करती है.

getArtManagerLocal().cancelBackgroundDexoptJob();

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

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

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

// Process the result here.
...

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

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

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

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

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

अगर आपको किसी कॉलबैक को हटाना है, तो उसे जोड़ते समय उसका रेफ़रंस सेव करें. इसके बाद, 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 सेवा खुद ही डेक्सऑप्ट ऑपरेशन शुरू करती है. अगर आपको उन कार्रवाइयों के लिए, पैकेज की सूची या 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 सेवा से शुरू होने वाला कोई भी dexopt ऑपरेशन, BatchDexoptStartCallback को ट्रिगर करता है. 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 की प्रोसेस, बूट और बैकग्राउंड dexopt के दौरान ART सेवा ने शुरू की है या dexoptPackage एपीआई कॉल ने.

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

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

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

अगर आपको कॉल बैक की सुविधा बंद करनी है, तो ArtManagerLocal#clearAdjustCompilerFilterCallback का इस्तेमाल करें.

getArtManagerLocal().clearAdjustCompilerFilterCallback();

अन्य कस्टमाइज़ेशन

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

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

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

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

बैकग्राउंड dexopt जॉब को Job Scheduler मैनेज करता है. इसका जॉब आईडी 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>

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

आम तौर पर, एआरटी सेवा प्रोफ़ाइल का इस्तेमाल इन वजहों से नहीं करती:

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