ก่อนเริ่มต้น โปรดดูภาพรวมระดับสูงของบริการ ART
ตั้งแต่ Android 14 เป็นต้นไป บริการ ART จะจัดการการคอมไพล์ AOT ในอุปกรณ์สำหรับ แอป (หรือที่เรียกว่า dexopt) บริการ ART เป็นส่วนหนึ่งของโมดูล 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 (ค่าเริ่มต้น: speed)
นี่คือตัวกรองคอมไพเลอร์สำรองสำหรับแอปที่แอปอื่นๆ ใช้
โดยหลักการแล้ว บริการ ART จะทำการคอมไพล์ที่แนะนำโดยโปรไฟล์ (speed-profile
) สำหรับ
แอปทั้งหมดเมื่อเป็นไปได้ ซึ่งมักจะเกิดขึ้นระหว่าง dexopt ที่ทำงานอยู่เบื้องหลัง อย่างไรก็ตาม มี
บางแอปที่แอปอื่นๆ ใช้ (ไม่ว่าจะผ่าน <uses-library>
หรือโหลด
แบบไดนามิกโดยใช้ Context#createPackageContext
กับ
CONTEXT_INCLUDE_CODE
) แอปดังกล่าวไม่สามารถใช้โปรไฟล์ในเครื่อง
ได้เนื่องด้วยเหตุผลด้านความเป็นส่วนตัว
สำหรับแอปดังกล่าว หากมีการขอการคอมไพล์ที่แนะนำโดยโปรไฟล์ บริการ ART จะพยายามใช้โปรไฟล์ในระบบคลาวด์ก่อน หากไม่มีโปรไฟล์ระบบคลาวด์ ART Service
จะกลับไปใช้ตัวกรองคอมไพเลอร์ที่ระบุโดย 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 ซึ่งจะมีประโยชน์อย่างยิ่งในระหว่าง
การบูต
อย่างไรก็ตาม การเรียกใช้ dex2oat มากเกินไปอาจทำให้อุปกรณ์มีหน่วยความจำไม่เพียงพอ แม้ว่าปัญหานี้จะลดลงได้โดยการตั้งค่า dalvik.vm.dex2oat-swap
เป็น true
เพื่ออนุญาตให้ใช้ไฟล์สวอป การเรียกใช้มากเกินไปอาจทำให้เกิด
การสลับบริบทที่ไม่จำเป็นด้วย ดังนั้น คุณควรปรับตัวเลขนี้อย่างระมัดระวัง
โดยพิจารณาจากผลิตภัณฑ์แต่ละรายการ
pm.dexopt.downgrade_after_inactive_days (ค่าเริ่มต้น: ไม่ได้ตั้งค่า)
หากตั้งค่าตัวเลือกนี้ไว้ บริการ ART จะ dexopt เฉพาะแอปที่ใช้ภายในจำนวนวันที่ที่ระบุล่าสุด
นอกจากนี้ หากพื้นที่เก็บข้อมูลเหลือน้อยมาก ในระหว่างการเพิ่มประสิทธิภาพ DEX ในเบื้องหลัง บริการ 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 (ค่าเริ่มต้น: false)
ใช้สำหรับการทดสอบเท่านั้น ซึ่งจะป้องกันไม่ให้บริการ 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
เป็น Singleton ที่ 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());
}
นอกจากนี้ คุณยังส่งเหตุผลในการเพิ่มประสิทธิภาพ DEX ของคุณเองได้ด้วย หากทำเช่นนั้น คุณต้องตั้งค่าคลาสลำดับความสำคัญและตัวกรองคอมไพเลอร์อย่างชัดเจน
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
หรือโดยบริการ ART ให้ใช้ ArtManagerLocal#addDexoptDoneCallback
getArtManagerLocal().addDexoptDoneCallback(
false /* onlyIncludeUpdates */,
Runnable::run,
(result) -> {
// Process the result here.
...
});
อาร์กิวเมนต์แรกจะกำหนดว่าจะรวมเฉพาะการอัปเดตในผลลัพธ์หรือไม่ หากต้องการฟังเฉพาะแพ็กเกจที่ dexopt อัปเดต ให้ตั้งค่าเป็น true
อาร์กิวเมนต์ที่ 2 คือตัวดำเนินการของโค้ดเรียกกลับ หากต้องการเรียกใช้การเรียกกลับในเธรดเดียวกันกับที่ทำการเพิ่มประสิทธิภาพ DEX ให้ใช้ 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 ด้วยตัวเองในระหว่างการบูตและ 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 ด้วย
คุณต้องรวมโค้ดไว้ในการเรียกกลับรายการเดียว
// Bad example.
// Disable dexopt.
getArtManagerLocal().unscheduleBackgroundDexoptJob();
// Re-enable dexopt.
getArtManagerLocal().scheduleBackgroundDexoptJob();
การดำเนินการ dexopt ที่ดำเนินการในการติดตั้งแอปไม่ได้เริ่มต้นโดย ART
Service แต่จะเริ่มต้นโดยตัวจัดการแพ็กเกจผ่านการเรียกใช้ dexoptPackage
ดังนั้นจึงไม่ทริกเกอร์
BatchDexoptStartCallback
หากต้องการปิดใช้ dexopt เมื่อติดตั้งแอป ให้ป้องกันไม่ให้
Package Manager เรียกใช้ dexoptPackage
ลบล้างตัวกรองคอมไพเลอร์สำหรับบางแพ็กเกจ (Android 15 ขึ้นไป)
คุณลบล้างตัวกรองคอมไพเลอร์สำหรับแพ็กเกจบางรายการได้โดยการลงทะเบียน
การเรียกกลับผ่าน setAdjustCompilerFilterCallback
ระบบจะเรียกใช้การเรียกกลับ
เมื่อใดก็ตามที่จะมีการทำ Dexopt แพ็กเกจ ไม่ว่าการทำ Dexopt จะเริ่มต้นโดย
บริการ ART ระหว่างการบูตและการทำ Dexopt เบื้องหลัง หรือโดยการเรียกใช้ 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 ยังรองรับการปรับแต่งอื่นๆ อีกด้วย
ตั้งค่าเกณฑ์ความร้อนสำหรับ dexopt ในเบื้องหลัง
Job Scheduler จะควบคุมอุณหภูมิของงาน dexopt ในเบื้องหลัง
ระบบจะยกเลิกงานทันทีเมื่ออุณหภูมิถึง THERMAL_STATUS_MODERATE
คุณปรับเกณฑ์ของ
THERMAL_STATUS_MODERATE
ได้
ตรวจสอบว่า dexopt เบื้องหลังทำงานอยู่หรือไม่
Job Scheduler จะจัดการงาน 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
หากต้องการใช้โปรไฟล์เพื่อเป็นแนวทางในการเพิ่มประสิทธิภาพ DEX ให้วางไฟล์ .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 อาจใช้ได้ บรรทัดที่ 2 เรียกใช้ 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 (Checksum ในโปรไฟล์ไม่ตรงกับ
Checksum ของไฟล์
.dex
ใน APK)