يتوافق الإصدار 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 | غير محدود |
TOP | Visible |
BOUND_TOP | Visible |
FOREGROUND_SERVICE | غير مرئية |
BOUND_FOREGROUND_SERVICE | غير مرئية |
IMPORTANT_FOREGROUND | Visible |
IMPORTANT_BACKGROUND | غير مرئية |
TRANSIENT_BACKGROUND | غير مرئية |
BACKUP | غير مرئية |
SERVICE | غير مرئية |
RECEIVER | غير مرئية |
TOP_SLEEPING | Visible |
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)، لا تتوفّر للتطبيقات واجهة برمجة تطبيقات للاستعلام عن حدود الذاكرة في وقت التشغيل. على مصنّعي المعدات الأصلية أخذ ذلك في الاعتبار وتجنُّب ضبط الحدود منخفضة جدًا، ما يضمن عدم بلوغ التطبيقات الحدود خلال حالات الاستخدام المعقولة.
إعدادات عامة: تنطبق الحدود على جميع عمليات التطبيقات على الجهاز، بما في ذلك التطبيقات المثبّتة مسبقًا. لا تتوفّر قائمة مسموح بها لإعفاء تطبيقات معيّنة من هذه الحدود.
تعديل الإعدادات
لتغيير الحدود على مستوى النظام، اتّبِع الخطوات التالية:
- عدِّل الملف
/vendor/etc/memory-limiter-config.xml. - أعِد تشغيل الجهاز أو أعِد تشغيل
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 UIDadb 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 1234adb shell am memory-limiter manual 1234 none // Remove the manual override for PID 1234
لا تنطبق التجاوزات اليدوية إلا على دورة حياة العملية. إذا أعيد تشغيل العملية، ستعود إلى الحدود التلقائية استنادًا إلى حالتها.