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

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

الآلية

يتكامل "مقيّد الذاكرة" مع خدمة "مدير الأنشطة" (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) المسموح به للعمليات غير المرئية

إرشادات حول حد الذاكرة على الجهاز

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

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

    • العمليات المرئية: نصف إجمالي ذاكرة الوصول العشوائي (RAM) الفعلية على الأقل وثلثاها على الأكثر
    • العمليات غير المرئية: من ربع إجمالي ذاكرة الوصول العشوائي (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 حالة التشغيل لـ "مقيّد الذاكرة":

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

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