أداة تحديد الذاكرة

يتوافق الإصدار 17 من Android والإصدارات الأحدث مع أداة تحديد الذاكرة، وهي خدمة تابعة لنظام التشغيل تراقب استخدام الذاكرة لعمليات التطبيقات وتحدّ منه باستخدام Linux cgroup v2. تمنع أداة تحديد الذاكرة التطبيقات الفردية من استهلاك ذاكرة النظام بشكل مفرط، ما يقلّل من الضغط على الذاكرة على مستوى النظام ويمنع إنهاء العمليات المهمة بشكل مفرط بسبب نقص الذاكرة (OOM).

الآلية

تتكامل أداة تحديد الذاكرة مع خدمة "مدير الأنشطة" (AMS) لتتبُّع أحداث دورة حياة العملية وتغييرات الحالة. تفرض أداة تحديد الذاكرة حدود الذاكرة باستخدام نظام ملفات Linux kernel cgroup v2.

لاستخدام أداة تحديد الذاكرة، يجب أن تتيح نواة الجهاز cgroup v2 ووحدة التحكّم memory. تعتمد الخدمة تحديدًا على السمات التالية:

memory.high
حدّ مرن عند تجاوزه، يتم تقليل سرعة العملية ويحاول النواة استرداد الذاكرة منها.
memory.swap.max
يحدّ من مقدار مساحة التبديل التي يمكن للعملية استخدامها.

التأثير على التطبيقات

لا تتأثر التطبيقات التي لا تتجاوز حدود الذاكرة بأداة تحديد الذاكرة.

عندما يتجاوز أحد التطبيقات الحدّ memory.high، يزيل النواة الذاكرة المستندة إلى الملفات في التطبيق ويستبدل ذاكرته المجهولة لإبقاء التطبيق ضمن الحدّ. نتيجةً للإزالة والاستبدال، قد يعمل التطبيق بشكل أبطأ.

في الحالات القصوى، إذا استمر التطبيق في تخصيص ذاكرة مجهولة ولم تتوفّر مساحة تبديل على الجهاز، قد يتعذّر على التطبيق تخصيص الذاكرة، ومن المرجّح أن يتعطّل نتيجةً لذلك.

مراقبة العمليات

تراقب أداة تحديد الذاكرة عمليات التطبيقات (UID >= 10000) تلقائيًا. يتم عادةً استثناء عمليات النظام للمساعدة في التحقّق من استقرار النظام الأساسي.

تحدّد أداة تحديد الذاكرة حدود الذاكرة استنادًا إلى حالة العملية:

  • العمليات المرئية هي العمليات التي يمكن للمستخدم ملاحظتها، مثل الأنشطة في المقدّمة أو الخدمات في المقدّمة أو الحالات الأخرى التي يمكن ملاحظة حدوث تأخير فيها.

  • العمليات غير المرئية هي عمليات في الخلفية لا يتفاعل معها المستخدم أو لا يراها.

يربط الجدول التالي حالات العمليات المحدّدة بحدود الذاكرة:

حالة العمليةحد الذاكرة
PERSISTENTغير محدود
PERSISTENT_UIغير محدود
TOPVisible
BOUND_TOPVisible
FOREGROUND_SERVICEغير مرئية
BOUND_FOREGROUND_SERVICEغير مرئية
IMPORTANT_FOREGROUNDVisible
IMPORTANT_BACKGROUNDغير مرئية
TRANSIENT_BACKGROUNDغير مرئية
BACKUPغير مرئية
SERVICEغير مرئية
RECEIVERغير مرئية
TOP_SLEEPINGVisible
HEAVY_WEIGHTغير مرئية
HOMEغير مرئية
LAST_ACTIVITYغير مرئية
CACHED_ACTIVITYنسخة مخبأة
CACHED_ACTIVITY_CLIENTنسخة مخبأة
CACHED_RECENTنسخة مخبأة
CACHED_EMPTYنسخة مخبأة

في الحالة المخزّنة مؤقتًا، يتم تجميد العمليات ثم استردادها إلى أقصى حد.

عندما تتجاوز إحدى العمليات الحدّ memory.high المخصّص لها، ترصد أداة تحديد الذاكرة الحدث ويمكنها تشغيل إجراءات تصحيح الأخطاء، مثل التقاط ملف شخصي للذاكرة أو تسجيل حالة شاذة في statsd.

الإعداد

يمكنك إعداد أداة تحديد الذاكرة باستخدام ملف XML موجود على قسم vendor. يتيح لك الإعداد ضبط حدود الذاكرة المطلقة استنادًا إلى قيود الذاكرة المحدّدة للجهاز.

  • مسار الملف: /vendor/etc/memory-limiter-config.xml

  • الإعدادات التلقائية: إذا لم يتم العثور على ملف الإعداد أو إذا كان غير قابل للقراءة أو غير صالح، يتم إيقاف أداة تحديد الذاكرة.

تنسيق XML

يتّبع ملف الإعداد المخطط المحدّد في memory-limiter-config.xsd. يتيح لك الملف تحديد مجموعات حدود متعددة، وتختار الخدمة أفضل تطابق استنادًا إلى ذاكرة الوصول العشوائي (RAM) المتاحة للجهاز. يتم تحديد جميع قيم الذاكرة بوحدة الميبيبايت (MiB).

<MemoryLimiterConfig>
  <version>1</version>
  <configList>
    <limitSet>
      <!-- Limits for a phone with at least 14G of ram: 8G/4G/4G/4G -->
      <minimumRequiredMemTotal>14336</minimumRequiredMemTotal>
      <memVisible>8192</memVisible>
      <memNotVisible>4096</memNotVisible>
      <swapVisible>4096</swapVisible>
      <swapNotVisible>4096</swapNotVisible>
    </limitSet>
  </configList>
</MemoryLimiterConfig>
version
عدد صحيح موجب يحدّد إصدار الإعداد. يجب أن يكون هذا العدد 1.
minimumRequiredMemTotal
الحد الأدنى المطلوب من ذاكرة النظام المتاحة لكي تكون مجموعة الحدود هذه صالحة.
memVisible
حد الذاكرة (memory.high) المسموح به للعمليات المرئية.
memNotVisible
حد الذاكرة (memory.high) المسموح به للعمليات غير المرئية.
swapVisible
حد التبديل (memory.swap.max) المسموح به للعمليات المرئية.
swapNotVisible
حد التبديل (memory.swap.max) المسموح به للعمليات غير المرئية.

تعديل الإعدادات

لتغيير الحدود على مستوى النظام، اتّبِع الخطوات التالية:

  1. عدِّل الملف /vendor/etc/memory-limiter-config.xml.
  2. أعِد تشغيل الجهاز أو أعِد تشغيل system_server لتفعيل التغييرات.

أوامر Shell

يتيح لك الأمر am memory-limiter وللمطوّرين التفاعل مع الخدمة في وقت التشغيل لأغراض التطوير والاختبار:

am memory-limiter <SUB-COMMAND>

status

يعرض الأمر الفرعي status حالة التشغيل لأداة تحديد الذاكرة:

adb shell am memory-limiter status

مثال على الإخراج:

Memory limiter
  enabled                  monitoring=true          ignored=none
  visibleMem=1948MB        visibleSwap=974MB
  notVisibleMem=974MB      notVisibleSwap=487MB
  started=36               watched=36               watch-failed=0
  events=0                 processes=36             process-hwm=36

تشمل الحقول الرئيسية في الإخراج ما يلي:

monitoring
يشير إلى ما إذا كانت أداة تحديد الذاكرة تراقب العمليات بنشاط.
visibleMem وnotVisibleMem
تشيران إلى حدود الذاكرة المطلقة المحسوبة لكل حالة.
events
عدد المرات التي تجاوزت فيها إحدى العمليات الحدّ المسموح به.
processes
عدد العمليات التي تتم مراقبتها.

ignore

يستبعد الأمر الفرعي ignore مؤقتًا معرّف مستخدم أو جميع العمليات من أن تكون محدودة. يكون هذا الإجراء مفيدًا لاختبار الأداء أو عند السماح لتطبيق معيّن بتجاوز حدوده.

adb shell am memory-limiter ignore 10087  // Ignore a specific UID
adb shell am memory-limiter ignore all    // Ignore all processes (effectively disables limiting)
adb shell am memory-limiter ignore none   // Resume normal operation

manual

يتجاوز الأمر الفرعي manual الحدود المحسوبة لعملية معيّنة (حسب معرّف العملية) بقيمة مطلقة مخصّصة بالميغابايت (MB):

adb shell am memory-limiter manual 1234 1024   // Set a 1024 MB limit for PID 1234
adb shell am memory-limiter manual 1234 none // Remove the manual override for PID 1234

لا تنطبق عمليات التجاوز اليدوية إلا على دورة حياة العملية. إذا أعيد تشغيل العملية، ستعود إلى الحدود التلقائية استنادًا إلى حالتها.