إعدادات خدمة ART

قبل البدء، يمكنك إلقاء نظرة عامة وشاملة على خدمة ART.

بدءًا من الإصدار Android 14، ستتوفر ميزة تجميع AOT على الجهاز فقط معالجة التطبيقات (المعروفة أيضًا باسم dexopt) من خلال خدمة ART. خدمة ART هي جزء من ART ويمكنك تخصيصه من خلال خصائص النظام وواجهات برمجة التطبيقات.

خصائص النظام

تدعم خدمة ART جميع خيارات dex2oat

بالإضافة إلى ذلك، تتوافق خدمة ART مع خصائص النظام التالية:

pm.dexopt.<reason>

هذا عبارة عن مجموعة من خصائص النظام التي تحدد عوامل تصفية التجميع التلقائي لكل أسباب التجميع المحددة مسبقًا والموضحة في سيناريوهات إيقاف عرض المحتوى.

لمزيد من المعلومات، يُرجى مراجعة فلاتر برامج التجميع:

القيم التلقائية العادية هي:

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 عملية تجميع إرشادي للملف الشخصي (speed-profile) لـ جميع التطبيقات متى أمكن، وذلك عادةً أثناء تشغيل البيانات في الخلفية. ومع ذلك، هناك بعض التطبيقات التي تستخدمها تطبيقات أخرى (إما من خلال <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. وهذا يعني أنّ الحد الأقصى لعدد سلاسل المحادثات المتزامنة هو ناتج خاصيتَي النظام.
  • ربط dalvik.vm.*dex2oat-cpu-set والملفات الشخصية للمهام دائمًا بوحدة المعالجة المركزية (CPU) الأساسية الاستخدام، بغض النظر عن الحد الأقصى لعدد سلاسل المحادثات المتزامنة (تمت مناقشتها أعلاه).

قد لا يستخدم استدعاء dex2oat واحد جميع نوى وحدة المعالجة المركزية (CPU) بشكل كامل، بغض النظر عن من dalvik.vm.*dex2oat-threads. وبالتالي، تؤدي زيادة عدد dex2oat للاستدعاءات (pm.dexopt.<reason>.concurrency) يمكن أن تستخدم نوى وحدة المعالجة المركزية بشكل أفضل، وتسريع التقدم الإجمالي لـ dexopt. يكون هذا مفيدًا بشكل خاص أثناء .

ومع ذلك، قد يؤدي وجود عدد كبير جدًا من استدعاءات dex2oat إلى نفاد مساحة على الرغم من أنّه يمكن الحدّ من حدوث ذلك عن طريق ضبط dalvik.vm.dex2oat-swap على true للسماح باستخدام ملف تبديل. قد يتسبب عدد كبير جدًا من الاستدعاءات أيضًا في التبديل غير الضروري للسياق. لذلك، يجب ضبط هذا الرقم بعناية على أساس كل منتج على حدة.

pm.dexopt.downgrad_after_inactive_days (الإعداد التلقائي: لم يتم الضبط)

وإذا تم تعيين هذا الخيار، لا تعتمد خدمة ART إلا التطبيقات المستخدمة ضمن آخر تطبيق عدد الأيام.

بالإضافة إلى ذلك، إذا كانت مساحة التخزين منخفضة تقريبًا، يمكن استخدام خدمة ART أثناء الاستخدام في الخلفية. خفض مستوى فلتر التجميع للتطبيقات التي لا يتم استخدامها خلال آخر مرة عدد الأيام لإخلاء بعض المساحة. سبب التجميع لذلك هو inactive، ويتم تحديد عامل تصفية التجميع بواسطة pm.dexopt.inactive. المساحة إنّ الحدّ الأدنى لتفعيل هذه الميزة هو الحدّ الأدنى للمساحة المنخفضة في "أداة إدارة مساحة التخزين". (قابلة للتهيئة من خلال الإعدادات العامة sys_storage_threshold_percentage sys_storage_threshold_max_bytes، الحجم التلقائي: 500 ميغابايت) بالإضافة إلى 500 ميغابايت.

إذا قمت بتخصيص قائمة الحزم من خلال ArtManagerLocal#setBatchDexoptStartCallback، الحِزم في القائمة المتوفّرة بحلول BatchDexoptStartCallback لـ bg-dexopt، لا يتم إرجاعها إلى إصدار سابق مطلقًا.

pm.dexopt.disable_bg_dexopt (القيمة التلقائية: خطأ)

هذه الميزة مخصَّصة للاختبار فقط. يمنع خدمة ART من جدولة الخلفية. وظيفة dexopt.

إذا تمت جدولة مهمة dexopt في الخلفية من قبل، ولكن لم يتم تشغيلها بعد، سيتم لن يكون له أي تأثير. وهذا يعني أن الوظيفة ستستمر.

يشير هذا المصطلح إلى تسلسل مقترَح من الأوامر لمنع مهمة تحسين الخلفية من الجري هو:

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

يمنع السطر الأول جدولة مهمة ضبط الخلفية، إذا كانت لم يتم تحديد موعدها بعد. يلغي السطر الثاني جدولة مهمة ضبط الخلفية، إذا إلا أنه قد تمت جدولته مسبقًا، ويلغي فورًا مهمة ضبط الخلفية، إذا إنه قيد التشغيل.

واجهات برمجة التطبيقات لخدمة ART

تعرض خدمة ART واجهات برمجة تطبيقات Java للتخصيص. يتم تحديد واجهات برمجة التطبيقات في 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;

تتطلّب معظم واجهات برمجة التطبيقات نسخة افتراضية من PackageManagerLocal.FilteredSnapshot، الذي يحتفظ بمعلومات جميع التطبيقات. يمكنك الحصول عليه من خلال الاتصال PackageManagerLocal#withFilteredSnapshot، حيث PackageManagerLocal أيضًا سينجلتون الذي يحمله LocalManagerRegistry ويمكن الحصول عليه من com.android.server.pm.PackageManagerServiceUtils#getPackageManagerLocal

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

في ما يلي بعض حالات الاستخدام النموذجي لواجهات برمجة التطبيقات.

تشغيل dexopt لأحد التطبيقات

يمكنك تفعيل dexopt أيّ تطبيق في أي وقت من خلال الاتصال. ArtManagerLocal#dexoptPackage

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

يمكنك أيضًا اختيار سبب إثبات الملكية الخاص بك. إذا قمت بذلك، فسيتم تحديد فئة الأولوية يجب تعيين عامل تصفية التجميع بشكل صريح.

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

إلغاء الاشتراك

في حال بدء عملية من خلال استدعاء 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، سواء كانت العملية تبدأه مكالمة dexoptPackage أو من خلال خدمة ART، استخدم ArtManagerLocal#addDexoptDoneCallback

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

وتحدِّد الوسيطة الأولى ما إذا كان سيتم تضمين التعديلات في النتيجة فقط أم لا. في حال حذف فإنك تريد فقط الاستماع إلى الحزم التي يتم تحديثها بواسطة dexopt، فما عليك سوى تعيينها على true.

الوسيطة الثانية هي منفذ تنفيذ رد الاتصال. لتنفيذ معاودة الاتصال على سلسلة المحادثات نفسها التي تنفّذ 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. لتخصيص قائمة الحزم أو معلمات 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();

تخصيص مَعلمات مهمة ضبط الخلفية

يتم تلقائيًا تنفيذ مهمة ضبط الخلفية مرة واحدة في اليوم عندما يكون الجهاز غير نشِط لفترة قصيرة. والشحن. يمكن تغيير ذلك باستخدام ArtManagerLocal#setScheduleBackgroundDexoptJobCallback

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

يمكنك ضبط ScheduleBackgroundDexoptJobCallback واحد كحدّ أقصى. الإجراء الذي سينفّذه معاودة الاتصال ستظل نشطة لجميع المكالمات المستقبلية ما لم تقوم بمحوها.

إذا كنت تريد محو معاودة الاتصال، فاستخدم ArtManagerLocal#clearScheduleBackgroundDexoptJobCallback

getArtManagerLocal().clearScheduleBackgroundDexoptJobCallback();

إيقاف 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 واحد على الأكثر. إذا كنت تريد أيضًا استخدام BatchDexoptStartCallback لتخصيص قائمة الحزم أو معلمات dexopt، يجب عليك دمج الرمز في معاودة اتصال واحدة.

// Bad example.

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

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

لا تبدأ ART عملية الاعتماد التي يتم إجراؤها عند تثبيت التطبيق الخدمة. بدلاً من ذلك، يتم بدؤه بواسطة مدير الحزمة من خلال مكالمة dexoptPackage. لذلك، لا يؤدي إلى تشغيل BatchDexoptStartCallback ولإيقافها عند تثبيت التطبيق، عليك منع مدير الحزمة من الاتصال بـ dexoptPackage.

تجاهُل فلتر برنامج التجميع في حِزم معيّنة (إصدار Android 15 (الإصدار التجريبي من AOSP) أو الإصدارات الأحدث)

يمكنك تجاوز عامل تصفية التجميع لحزم معينة من خلال تسجيل حتى setAdjustCompilerFilterCallback. تُسمى معاودة الاتصال متى يتم استخدام أي حزمة، بغض النظر عن بدء عملية العرض خدمة ART أثناء تشغيل الجهاز وفي الخلفية أو من خلال طلب بيانات من واجهة برمجة التطبيقات dexoptPackage

إذا كانت الحزمة لا تحتاج إلى تعديل، يجب أن يعود رد الاتصال originalCompilerFilter

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

يمكنك ضبط سمة AdjustCompilerFilterCallback واحدة فقط. إذا كنت تريد استخدام AdjustCompilerFilterCallback لإلغاء عامل تصفية التجميع لبرامج متعددة ، فيجب دمج التعليمة البرمجية في معاودة اتصال واحدة. تظل معاودة الاتصال نشطة لجميع المكالمات المستقبلية ما لم تمسحها.

إذا كنت تريد محو معاودة الاتصال، فاستخدم ArtManagerLocal#clearAdjustCompilerFilterCallback

getArtManagerLocal().clearAdjustCompilerFilterCallback();

تخصيصات أخرى

توفّر خدمة ART أيضًا بعض التخصيصات الأخرى.

ضبط الحدّ الأدنى لدرجة الحرارة في الخلفية

يتم تنفيذ التحكُّم الحراري في مهمة ضبط الخلفية من خلال أداة جدولة المهام. يتم إلغاء المهمة فورًا عندما تصل درجة الحرارة إلى 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.
  ...
}

توفير ملف شخصي للفهرسة

لاستخدام ملف شخصي لتوجيه عملية التحكّم، ضَع ملف .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. يشغِّل السطر الثاني 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).