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

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

آلية العمل

يتكامل أداة Memory Limiter مع خدمة Activity Manager Service (AMS) لتتبُّع أحداث دورة حياة العمليات وتغييرات الحالة. يفرض Memory Limiter حدود الذاكرة باستخدام نظام ملفات cgroup v2 في نواة Linux.

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

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

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

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

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

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

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

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

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

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

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

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

حالة العمليةحد الذاكرة
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، يرصد أداة Memory Limiter الحدث ويمكنه بدء إجراءات تصحيح الأخطاء، مثل تسجيل ملف تعريف الذاكرة أو تسجيل خلل في statsd.

الإعداد

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

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

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

تنسيق XML

يتّبع ملف الإعداد المخطط المحدّد في memory-limiter-config.xsd. يتيح لك الملف تحديد مجموعات حدود متعددة، وتختار الخدمة المجموعة الأنسب استنادًا إلى ذاكرة الوصول العشوائي المتاحة على الجهاز. يتم تحديد جميع قيم الذاكرة بوحدات الميبيبايت (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) المسموح به للعمليات غير المرئية

إرشادات الحد الأقصى لذاكرة الجهاز

عند ضبط حدود الذاكرة لجهازك، يُرجى مراعاة الإرشادات التالية:

  • تخصيص الحدود حسب إمكانات الجهاز: يمكن لمصنّعي الأجهزة الأصليين ضبط حدود مخصّصة حسب إمكانات أجهزتهم. يقترح نظام التشغيل Android النطاقات التالية:

    • العمليات المرئية: يجب أن تشغل هذه العمليات ما لا يقل عن نصف إجمالي ذاكرة الوصول العشوائي (RAM) الفعلية وما لا يزيد عن ثلثَيها.
    • العمليات غير المرئية: من ربع إلى ثلث إجمالي ذاكرة الوصول العشوائي الفعلية يمكن لمصنّعي المعدات الأصلية اتّخاذ قرارات مختلفة استنادًا إلى إمكانات الجهاز وحالات الاستخدام.
  • عدم توفّر واجهة برمجة تطبيقات لوقت التشغيل للتطبيقات: اعتبارًا من Android 17 (الإصدار 37 من حزمة تطوير البرامج)، لا تتضمّن التطبيقات واجهة برمجة تطبيقات للاستعلام عن حدود الذاكرة في وقت التشغيل. على الشركات المصنّعة للأجهزة الأصلية مراعاة ذلك وتجنُّب وضع حدود منخفضة جدًا، مع ضمان عدم تجاوز التطبيقات لهذه الحدود خلال حالات الاستخدام المعقولة.

  • الإعدادات العامة: تنطبق الحدود على جميع عمليات التطبيقات على الجهاز، بما في ذلك التطبيقات المثبَّتة مسبقًا. ولا تتوفّر قائمة مسموح بها لإعفاء بعض التطبيقات من هذه الحدود.

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

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

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

أوامر Shell

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

am memory-limiter <SUB-COMMAND>

status

يعرض الأمر الفرعي status حالة التشغيل الخاصة بأداة Memory Limiter:

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 مؤقتًا معرّف UID أو جميع العمليات من أن تكون محدودة. ويكون هذا الإجراء مفيدًا لاختبار الأداء أو عند السماح لتطبيق معيّن بتجاوز حدوده.

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 الحدود المحسوبة لعملية معيّنة (حسب معرّف العملية) بقيمة مطلقة مخصّصة بالبايت. يجب أن تكون القيمة عددًا صحيحًا، ولكن يمكن أن تتضمّن اللاحقة "MB" للإشارة إلى ميغابايت أو اللاحقة "GB" للإشارة إلى غيغابايت:

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

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

لا يمكن أن يتجاوز التعديل اليدوي أي حدود حالية للنظام.