การกำหนดค่าบริการ ART

ก่อนที่คุณจะเริ่มต้น โปรดดูภาพรวมระดับสูงของ ART Service

ตั้งแต่ Android 14 เป็นต้นไป การรวบรวม AOT ในอุปกรณ์สำหรับ แอป (หรือที่รู้จักในชื่อ dexopt) ได้รับการจัดการโดยบริการ ART ART Service เป็นส่วนหนึ่งของ ART และปรับแต่งโมดูลผ่านพร็อพเพอร์ตี้ของระบบและ API ได้

พร็อพเพอร์ตี้ของระบบ

บริการ ART สนับสนุน ตัวเลือก dex2oat

นอกจากนี้ บริการ ART ยังรองรับพร็อพเพอร์ตี้ของระบบต่อไปนี้

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 (ค่าเริ่มต้น: ความเร็ว)

นี่คือตัวกรองคอมไพเลอร์สำรองสำหรับแอปที่แอปอื่นๆ ใช้

โดยหลักการแล้ว ART Service จะรวมการรวบรวมแบบมีโปรไฟล์ (speed-profile) สำหรับ แอปทั้งหมดหากเป็นไปได้ โดยปกติจะใช้ในระหว่าง Dexopt ในเบื้องหลัง อย่างไรก็ตาม มี แอปบางแอปที่แอปอื่นใช้ (ทั้งผ่าน <uses-library> หรือแบบโหลด แบบไดนามิกโดยใช้ Context#createPackageContext กับ CONTEXT_INCLUDE_CODE) แอปดังกล่าวใช้ในเครื่องไม่ได้ โปรไฟล์ด้วยเหตุผลด้านความเป็นส่วนตัว

สำหรับแอปดังกล่าว หากมีการร้องขอการคอมไพล์ตามคำแนะนำโปรไฟล์ ให้ใช้บริการ ART ก่อน พยายามใช้โปรไฟล์ระบบคลาวด์ หากไม่มีโปรไฟล์ในระบบคลาวด์ บริการ ART กลับไปใช้ตัวกรองคอมไพเลอร์ที่ระบุโดย pm.dexopt.shared

หากการคอมไพล์ที่ขอไม่ใช่การแนะนำโปรไฟล์ พร็อพเพอร์ตี้นี้จะไม่มีผล

pm.dexopt.<reason>.concurrency (ค่าเริ่มต้น: 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 ซึ่งหมายความว่า จำนวนชุดข้อความพร้อมกันสูงสุดคือ ผลคูณของพร็อพเพอร์ตี้ระบบ 2 รายการ
  • dalvik.vm.*dex2oat-cpu-set และโปรไฟล์งานจะเชื่อมโยงแกนของ CPU เสมอ ไม่ว่าจะมีจำนวนชุดข้อความพร้อมกันสูงสุดเท่าใดก็ตาม (กล่าวถึง ที่ด้านบน)

การเรียกใช้ dex2oat รายการเดียวอาจไม่ได้ใช้แกน CPU ทั้งหมดอย่างเต็มที่ ไม่ว่าจะ จาก dalvik.vm.*dex2oat-threads ดังนั้น การเพิ่มจำนวน dex2oat การเรียกใช้ (pm.dexopt.<reason>.concurrency) สามารถใช้แกน CPU ได้ดีกว่าเพื่อ ทำให้ dexopt ทำงานได้เร็วขึ้น ซึ่งจะเป็นประโยชน์อย่างยิ่งในระหว่าง Boot

แต่การมีการเรียกใช้ dex2oat มากเกินไปอาจทำให้อุปกรณ์ทำงานไม่เต็มประสิทธิภาพ หน่วยความจำนี้ โดยสามารถลดทอนได้โดยการตั้งค่า dalvik.vm.dex2oat-swap เป็น true เพื่ออนุญาตให้ใช้ไฟล์การสลับ การเรียกใช้มากเกินไปอาจทำให้ การสลับบริบทโดยไม่จำเป็น ดังนั้น ตัวเลขนี้ควรผ่านการปรับแต่งอย่างระมัดระวัง เป็นรายผลิตภัณฑ์

pm.dexopt.downgrad_after_inactive_days (ค่าเริ่มต้น: ไม่ได้ตั้งค่า)

หากตั้งค่าตัวเลือกนี้ บริการ ART จะถอดรหัสเฉพาะแอปที่ใช้ในช่วง จำนวนวัน

นอกจากนี้ หากพื้นที่เก็บข้อมูลเหลือน้อย ในช่วง Dexopt พื้นหลัง บริการ ART ดาวน์เกรดตัวกรองคอมไพเลอร์ของแอปที่ไม่ได้ใช้ภายในครั้งสุดท้าย จำนวนวัน เพื่อเพิ่มพื้นที่ว่าง เหตุผลที่คอมไพเลอร์เป็นเช่นนี้คือ inactive และตัวกรองคอมไพเลอร์จะกำหนดโดย pm.dexopt.inactive พื้นที่ทำงาน เกณฑ์ที่จะทริกเกอร์ฟีเจอร์นี้คือเกณฑ์พื้นที่ต่ำของตัวจัดการพื้นที่เก็บข้อมูล (กำหนดค่าได้ผ่านการตั้งค่าส่วนกลาง sys_storage_threshold_percentage และ sys_storage_threshold_max_bytes, ค่าเริ่มต้น: 500 MB) บวก 500 MB

หากคุณปรับแต่งรายการแพ็กเกจโดยใช้ ArtManagerLocal#setBatchDexoptStartCallback, แพ็กเกจในรายการที่ให้ไว้ ภายใน BatchDexoptStartCallback สำหรับ bg-dexopt จะไม่ถูกปรับลดรุ่น

pm.dexopt.disable_bg_dexopt (ค่าเริ่มต้น: เท็จ)

ใช้สำหรับการทดสอบเท่านั้น ป้องกันไม่ให้บริการ ART ตั้งเวลาที่ทำงานอยู่เบื้องหลัง งาน dexopt

หากกำหนดเวลางาน dexopt ในเบื้องหลังไว้แล้ว แต่ยังไม่ได้ทำงาน การดำเนินการนี้ จะไม่มีผล กล่าวคือ งานจะยังคงทำงานอยู่

ลำดับคำสั่งที่แนะนำเพื่อป้องกันไม่ให้งาน Dexopt เบื้องหลัง กำลังทำงานคือ:

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

บรรทัดแรกจะป้องกันไม่ให้มีการกำหนดเวลางาน Dexopt ในเบื้องหลัง หาก ยังไม่ได้กำหนดเวลา บรรทัดที่ 2 ยกเลิกกำหนดเวลางาน Dexopt ในเบื้องหลัง ตั้งเวลาไว้แล้ว และยกเลิกงาน Dexopt พื้นหลังทันที กำลังทำงาน

API บริการ ART

บริการ ART แสดง Java API สำหรับการปรับแต่ง ระบบจะกําหนด API ใน ArtManagerLocal ดู Javadoc ใน art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java สำหรับ (แหล่งที่มาของ Android 14, แหล่งที่มาของการพัฒนาที่ยังไม่เปิดตัว)

ArtManagerLocal เป็นซิงเกิลตันของ LocalManagerRegistry ผู้ช่วย ฟังก์ชัน com.android.server.pm.DexOptHelper#getArtManagerLocal ช่วยให้คุณ หาได้

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

API ส่วนใหญ่ต้องการอินสแตนซ์ของ PackageManagerLocal.FilteredSnapshot ซึ่งเก็บข้อมูลของแอปทั้งหมด คุณสามารถรับได้ด้วยการโทร PackageManagerLocal#withFilteredSnapshot โดยที่ PackageManagerLocal ก็ ซิงเกิลตันที่ถือครองโดย LocalManagerRegistry และสามารถดึงข้อมูลจาก com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal

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

ต่อไปนี้คือกรณีการใช้งานทั่วไปของ API

เรียกใช้ dexopt สำหรับแอป

คุณสามารถเรียกใช้ dexopt สำหรับแอปใดๆ ได้ตลอดเวลาโดยการโทร ArtManagerLocal#dexoptPackage

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 Service ยังเริ่มดำเนินการ dexopt ด้วยตัวเองในหลายสถานการณ์ เช่น dexopt พื้นหลัง หากต้องการฟังผลลัพธ์ dexopt ทั้งหมด ไม่ว่าจะเป็นการดำเนินการ เริ่มต้นโดยการโทร dexoptPackage หรือโดยบริการ ART ให้ใช้ ArtManagerLocal#addDexoptDoneCallback

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

อาร์กิวเมนต์แรกกำหนดว่าจะรวมเฉพาะการอัปเดตในผลลัพธ์หรือไม่ ถ้า คุณต้องการฟังเฉพาะแพ็กเกจที่อัปเดตโดย dexopt เท่านั้น ให้ตั้งค่าเป็น "จริง"

อาร์กิวเมนต์ที่ 2 คือตัวดำเนินการของ Callback หากต้องการเรียกใช้ Callback ใน เทรดเดียวกันกับที่ใช้ dexopt ให้ใช้ Runnable::run ถ้าคุณไม่ต้องการให้ Callback เพื่อบล็อก dexopt ให้ใช้ตัวดำเนินการแบบไม่พร้อมกัน

คุณเพิ่ม Callback หลายรายการได้ แล้วบริการ ART จะดำเนินการทั้งหมด อย่างเป็นลำดับ Callback ทั้งหมดจะยังคงทำงานอยู่สำหรับการโทรในอนาคตทั้งหมด ยกเว้น ให้คุณนำเขาออก

หากคุณต้องการนำ Callback ออก ให้เก็บการอ้างอิง Callback ไว้เมื่อคุณ เพิ่มและใช้ 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 เองระหว่างการเปิดเครื่องและการทำงานเบื้องหลัง 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 ได้สูงสุด 1 รายการ การเรียกกลับจะยังคงอยู่ ใช้ได้กับการโทรทั้งหมดในอนาคต เว้นแต่ว่าคุณจะล้างข้อมูล

หากคุณต้องการล้างการเรียกกลับ ให้ใช้ ArtManagerLocal#clearBatchDexoptStartCallback

getArtManagerLocal().clearBatchDexoptStartCallback();

ปรับแต่งพารามิเตอร์ของงาน Dexopt พื้นหลัง

โดยค่าเริ่มต้น งาน Dexopt ในเบื้องหลังจะทำงานวันละครั้งเมื่อไม่มีการใช้งานอุปกรณ์ และกำลังชาร์จอยู่ คุณเปลี่ยนค่านี้ได้โดยใช้ ArtManagerLocal#setScheduleBackgroundDexoptJobCallback

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

คุณสามารถตั้ง ScheduleBackgroundDexoptJobCallback ได้สูงสุด 1 รายการ การเรียกกลับจะ ยังใช้ได้สำหรับการโทรทั้งหมดในอนาคต เว้นแต่คุณจะล้างข้อมูลเอาไว้

หากคุณต้องการล้างการเรียกกลับ ให้ใช้ ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback

getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();

ปิดใช้ dexopt ชั่วคราว

การดำเนินการ dexopt ที่เริ่มต้นโดยบริการ ART จะทริกเกอร์ 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 ได้สูงสุด 1 รายการ หากต้องการใช้ BatchDexoptStartCallback เพื่อปรับแต่งรายการแพ็กเกจหรือพารามิเตอร์ dexopt คุณต้องรวมโค้ดไว้ใน Callback เดียว

// Bad example.

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

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

การดำเนินการ dexopt กับการติดตั้งแอปไม่ได้เริ่มโดย ART บริการ แต่จะเริ่มต้นโดยตัวจัดการแพ็กเกจผ่าน dexoptPackage สาย ดังนั้นจึงไม่ทริกเกอร์ BatchDexoptStartCallback หากต้องการปิดใช้ dexopt ในการติดตั้งแอป ให้ป้องกัน ผู้จัดการแพ็กเกจไม่ให้โทรหา dexoptPackage

ลบล้างตัวกรองคอมไพเลอร์สำหรับแพ็กเกจบางรายการ (Android 15 ขึ้นไป)

คุณสามารถลบล้างตัวกรองคอมไพเลอร์สำหรับแพ็กเกจบางรายการได้โดยการลงทะเบียน โทรกลับผ่าน setAdjustCompilerFilterCallback Callback เรียกว่า เมื่อใดก็ตามที่จะมีการปรับแพ็กเกจ (Dexopt) ไม่ว่า Dexopt จะเริ่มต้นโดย บริการ ART ระหว่างการเปิดเครื่องและ Dexopt เบื้องหลังหรือโดยการเรียก API ของ dexoptPackage

หากแพ็กเกจไม่จำเป็นต้องมีการปรับเปลี่ยน คุณจะต้องส่งกลับ Callback originalCompilerFilter

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

คุณตั้งค่า AdjustCompilerFilterCallback ได้เพียง 1 รายการเท่านั้น หากคุณต้องการใช้งาน AdjustCompilerFilterCallback เพื่อลบล้างตัวกรองคอมไพเลอร์สำหรับหลายรายการ คุณต้องรวมโค้ดเป็น Callback เดียว Callback ยังคงอยู่ ใช้ได้กับการโทรทั้งหมดในอนาคต เว้นแต่ว่าคุณจะล้างข้อมูล

หากคุณต้องการล้างการเรียกกลับ ให้ใช้ ArtManagerLocal#clearAdjustCompilerFilterCallback

getArtManagerLocal().clearAdjustCompilerFilterCallback();

การปรับแต่งอื่นๆ

บริการ ART ยังรองรับการปรับแต่งอื่นๆ ด้วย

กำหนดเกณฑ์ความร้อนสำหรับ Dexopt พื้นหลัง

การควบคุมความร้อนของงาน Dexopt พื้นหลังดำเนินการโดย Job Scheduler งานถูกยกเลิกทันทีเมื่ออุณหภูมิถึง THERMAL_STATUS_MODERATE เกณฑ์ของ รองรับเสียง THERMAL_STATUS_MODERATE

ระบุว่า Dexopt พื้นหลังทำงานอยู่หรือไม่

งาน Dexopt พื้นหลังได้รับการจัดการโดย Job Scheduler และรหัสงานคือ 27873780 หากต้องการตรวจสอบว่างานกำลังทำงานอยู่หรือไม่ ให้ใช้ API ของ 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 ถัดจาก APK

ไฟล์ .prof ต้องเป็นไฟล์โปรไฟล์แบบไบนารี และชื่อไฟล์ต้องเป็น ชื่อไฟล์ของ APK + .prof ตัวอย่างเช่น

base.apk.prof

ชื่อไฟล์ของไฟล์ .dm ต้องเป็นชื่อไฟล์ APK ที่มี ส่วนขยายถูกแทนที่ด้วย .dm ตัวอย่างเช่น

base.dm

หากต้องการยืนยันว่ามีการใช้โปรไฟล์สำหรับ dexopt ให้เรียกใช้ dexopt ด้วย speed-profileและตรวจสอบผลลัพธ์

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

บรรทัดแรกจะล้างโปรไฟล์ทั้งหมดที่สร้างโดยรันไทม์ (เช่น โปรไฟล์ที่อยู่ในรันไทม์ /data/misc/profiles) (หากมี) เพื่อตรวจสอบว่าโปรไฟล์ที่อยู่ถัดจาก APK นั้น โปรไฟล์เดียวที่ ART Service ใช้งานได้ บรรทัดที่สองเรียกใช้ 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}

สาเหตุทั่วไปที่บริการ ART ไม่ใช้โปรไฟล์มีดังนี้

  • โปรไฟล์มีชื่อไฟล์ไม่ถูกต้องหรือไม่ได้อยู่ถัดจาก APK
  • โปรไฟล์อยู่ในรูปแบบที่ไม่ถูกต้อง
  • โปรไฟล์ไม่ตรงกับ APK (การตรวจสอบข้อผิดพลาดในโปรไฟล์ไม่ จับคู่การตรวจสอบข้อผิดพลาดของไฟล์ .dex ใน APK)