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