إنّ البرنامج الخفي لاختراق الذاكرة المنخفض (lmkd
) في Android يراقب حالة الذاكرة
في نظام Android قيد التشغيل ويتفاعل مع ارتفاع ضغط الذاكرة من خلال إيقاف
العمليات الأقل أهمية للحفاظ على أداء النظام
ضمن مستويات مقبولة.
لمحة عن الضغط على الذاكرة
قد يواجه نظام Android الذي يشغِّل عمليات متعدّدة بشكل موازٍ حالات يتم فيها استنفاد ذاكرة النظام وتواجه العمليات التي تتطلّب مزيدًا من الذاكرة تأخيرات ملحوظة. ضغط الذاكرة، وهي حالة ينقص فيها استهلاك النظام في الذاكرة، وتتطلّب من Android إخلاء مساحة في الذاكرة (لتخفيف الضغط) من خلال تقييد العمليات غير المهمة أو إيقافها، وطلب العمليات لإخلاء بعض الموارد المخزّنة مؤقتًا غير المهمة، وما إلى ذلك.
في السابق، كان نظام Android يراقب الضغط على ذاكرة النظام باستخدام برنامج تشغيل "مُشغِّل الذاكرة المنخفضة" (LMK) المضمّن في النواة، وهي آلية صارمة تعتمد على قيم مُبرمَجة بشكلٍ ثابت. اعتبارًا من الإصدار 4.12 من kernel، تمت إزالة برنامج تشغيل LMK من kernel المتوافق مع الإصدارات السابقة، وأصبح lmkd
في مساحة المستخدم ينفِّذ مهام مراقبة الذاكرة وإغلاق العمليات.
معلومات حول توقُّف الضغط
يتوافق Android 10 والإصدارات الأحدث مع وضع lmkd
جديد يستخدم أدوات رصد ضغط النواة (PSI) لرصد ضغط الذاكرة. تقيس مجموعة تصحيحات PSI في نواة الإصدار العلني (التي تم نقلها إلى نواة الإصدارَين 4.9 و4.14
) المدة التي يتأخّر فيها تنفيذ المهام نتيجةً لنقص
الذاكرة. وبما أنّ هذه التأخيرات تؤثّر مباشرةً في تجربة المستخدم، فإنّها представлява
مقياسًا مناسبًا لتحديد شدّة الضغط على الذاكرة. يتضمّن
الإصدار الأحدث من kernel أيضًا أدوات مراقبة PSI التي تسمح لعمليات مساحات المستخدمين المميّزة (مثل lmkd
) بتحديد الحدود القصوى لهذه التأخيرات والاشتراك
في الأحداث الواردة من kernel عند تجاوز الحدّ الأقصى.
أجهزة مراقبة PSI مقارنةً بإشارات vmpressure
بما أنّ إشارات vmpressure
(التي يتم إنشاؤها من خلال النواة لرصد lmkd
الذاكرة ويستخدمها lmkd
) غالبًا ما تتضمّن العديد من الإيجابيات الخاطئة،
يجب أن ينفّذ lmkd
عملية فلترة لتحديد ما إذا كانت الذاكرة تواجه ضغطًا حقيقيًا.
ويؤدي ذلك إلى عمليات تنشيط lmkd
غير ضرورية واستخدام موارد معالجة إضافية. يؤدي استخدام مراقبي PSI إلى رصد ضغط الذاكرة
بدقة أكبر وتقليل الوقت المستغرَق في الفلترة.
استخدام مراقبي PSI
لاستخدام مراقبي PSI بدلاً من أحداث vmpressure
، عليك ضبط السمة
ro.lmk.use_psi
. القيمة التلقائية هي true
، ما يجعل PSI يراقب
آلية رصد الضغط على الذاكرة التلقائية لlmkd
. بما أنّ أدوات مراقبة PSI تحتاج إلى مساعدة من kernel، يجب أن تتضمّن kernel تصحيحات PSI المتوافقة مع الإصدارات القديمة وأن تتم compiling مع تفعيل مساعدة PSI (CONFIG_PSI=y
).
عيوب برنامج تشغيل LMK داخل النواة
يوقِف Android نهائيًا برنامج تشغيل LMK بسبب عدد من المشاكل، بما في ذلك:
- كان يجب ضبط الأجهزة التي تحتوي على ذاكرة وصول عشوائي منخفضة بشكلٍ فعّال، وحتى في هذه الحالة، كان أداؤها سيئًا في عمليات المعالجة التي تتضمّن ذاكرة تخزين مؤقت نشطة كبيرة مستندة إلى الملفات. أدّى الأداء السيئ إلى حدوث تعذّر في الأداء وعدم تحقيق أي عمليات قتل.
- كان برنامج تشغيل LMK kernel يعتمد على حدود الذاكرة المتوفّرة، بدون تغيير الحجم استنادًا إلى الضغط على الذاكرة.
- بسبب صرامة التصميم، كان الشركاء يصِّبون غالبًا برنامج تشغيل لكي يعمل على أجهزتهم.
- تم تثبيت برنامج تشغيل LMK في واجهة برمجة تطبيقات تقليم الشرائح، والتي لم يتم تصميمها للعمليات الثقيلة مثل البحث عن الأهداف وقتلها، ما أدى إلى إبطاء عملية
vmscan
.
Userspace lmkd
ينفِّذ lmkd
في مساحة المستخدم الوظيفة نفسها التي يؤديها برنامج التشغيل المضمّن في النواة، ولكنه يستخدِم آليات النواة الحالية لرصد الضغط على الذاكرة وتقديره. وتشمل هذه
الآليات استخدام أحداث vmpressure
التي ينشئها kernel أو أدوات مراقبة معلومات PSI (الضغط المؤدي إلى توقُّف العمليات) للحصول على إشعارات بشأن مستويات الضغط في الذاكرة،
واستخدام ميزات cgroup للذاكرة للحد من موارد الذاكرة المخصّصة لكل
عملية استنادًا إلى أهمية العملية.
استخدام مساحة المستخدم lmkd في Android 10
في الإصدار 9 من Android والإصدارات الأحدث، يتم تفعيل lmkd
في مساحة المستخدم إذا
لم يتم رصد برنامج تشغيل LMK داخل النواة. بما أنّ مساحة المستخدم lmkd
تتطلّب توفُّر kernel لمجموعات cgroup للذاكرة، يجب تجميع kernel باستخدام
إعدادات الضبط التالية:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
استراتيجيات القتل
تتوافق ميزة Userspace lmkd
مع استراتيجيات الإغلاق استنادًا إلى أحداث vmpressure
أو فحوصات PSI
وشدة هذه المشاكل، بالإضافة إلى تلميحات أخرى، مثل استخدام التبديل. تختلف استراتيجية قتل التطبيقات
باختلاف الأجهزة ذات الذاكرة المنخفضة والأجهزة العالية الأداء:
- على الأجهزة ذات الذاكرة المنخفضة، يجب أن يتحمّل النظام ارتفاع ضغط الذاكرة كوضع طبيعي للعمل.
- في الأجهزة العالية الأداء، يجب اعتبار الضغط على الذاكرة حالة غير طبيعية وإصلاحها قبل أن تؤثّر في الأداء العام.
يمكنك ضبط استراتيجية الإيقاف باستخدام السمة ro.config.low_ram
. لمعرفة التفاصيل، يُرجى الاطّلاع على إعداد ذاكرة الوصول العشوائي المنخفضة.
تتيح مساحة المستخدم lmkd
أيضًا وضعًا قديمًا تتّخذ فيه قرارات إنهاء العمليات
باستخدام الاستراتيجيات نفسها المستخدَمة في برنامج تشغيل LMK المضمّن في النواة (أي حدود ذاكرة شغالة
ومخزّن مؤقت للملف). لتفعيل الوضع القديم، اضبط سمة
ro.lmk.use_minfree_levels
على true
.
ضبط lmkd
يمكنك إعداد lmkd
لجهاز محدَّد باستخدام السمات التالية.
الخاصية | استخدام | تلقائي |
---|---|---|
ro.config.low_ram
|
عليك تحديد ما إذا كان الجهاز مزوّدًا بذاكرة وصول عشوائي (RAM) منخفضة أو عالية الأداء. | false
|
ro.lmk.use_psi |
استخدام شاشات PSI (بدلاً من أحداث vmpressure ) |
true |
ro.lmk.use_minfree_levels
|
استخدِم حدود الذاكرة المتوفّرة وذاكرة التخزين المؤقت للملفات لاتخاذ قرارات بشأن قتل العمليات (أي مطابقة وظيفة برنامج تشغيل LMK المضمّن في kernel). | false
|
ro.lmk.low
|
الحد الأدنى لنتيجة oom_adj للعمليات المؤهَّلة
للإيقاف عند انخفاض مستوى vmpressure
|
1001 (غير مفعَّل) |
ro.lmk.medium
|
تمثل هذه السمة الحد الأدنى من نتيجة oom_adj للعمليات المؤهَّلة للإنهاء عند مستوى vmpressure متوسط.
|
800 (الخدمات المخزّنة مؤقتًا أو غير الأساسية) |
ro.lmk.critical
|
الحد الأدنى لنتيجة oom_adj للعمليات المؤهَّلة
للإيقاف عند مستوى vmpressure الحرج
|
0 (أي عملية) |
ro.lmk.critical_upgrade
|
تفعيل الترقية إلى المستوى الحرج. | false
|
ro.lmk.upgrade_pressure
|
الحد الأقصى mem_pressure الذي يتم عند بلوغه ترقية المستوى
لأنّ النظام يُجري عمليات تبديل كثيرة جدًا.
|
100 (غير مفعَّل) |
ro.lmk.downgrade_pressure
|
تمثّل هذه السمة الحدّ الأدنى mem_pressure الذي يتم عنده تجاهل حدث vmpressure بسبب توفّر مساحة كافية من الذاكرة الخالية.
|
100 (غير مفعَّل) |
ro.lmk.kill_heaviest_task
|
إيقاف المَهمّة المؤهّلة الأكثر استهلاكًا للطاقة (أفضل قرار) مقارنةً بأيّ مَهمّة مؤهّلة (قرار سريع). | false
|
ro.lmk.kill_timeout_ms
|
المدة بالملي ثانية بعد عملية قتل عندما لا تتم عملية قتل إضافية | 0 (غير مفعَّل) |
ro.lmk.debug
|
فعِّل سجلّات تصحيح أخطاء lmkd .
|
false
|
مثال على إعداد الجهاز:
PRODUCT_PROPERTY_OVERRIDES += \
ro.lmk.low=1001 \
ro.lmk.medium=800 \
ro.lmk.critical=0 \
ro.lmk.critical_upgrade=false \
ro.lmk.upgrade_pressure=100 \
ro.lmk.downgrade_pressure=100 \
ro.lmk.kill_heaviest_task=true
دالة lmkd في مساحة المستخدم في Android 11
يعمل نظام التشغيل Android 11 على تحسين lmkd
من خلال تقديم استراتيجية جديدة ل
إيقاف التطبيقات. تستخدِم استراتيجية الإغلاق آلية PSI لرصد الضغط على الذاكرة
التي تم تقديمها في Android 10. يراعي lmkd
في
Android 11 مستويات استخدام موارد الذاكرة
والتعطُّل لمنع نقص الذاكرة وانخفاض الأداء.
تحلّ استراتيجية الإيقاف هذه محل الاستراتيجيات السابقة ويمكن استخدامها على كلٍّ من
الأجهزة ذات الأداء العالي والأجهزة التي تتضمّن ذاكرة وصول عشوائي منخفضة (Android Go).
متطلبات النواة
بالنسبة إلى أجهزة Android 11، يتطلب lmkd
ميزات kernel التالية:
- يجب تضمين تصحيحات PSI وتفعيل PSI (تتوفّر الإصدارات القديمة في ملف "النواة الشائعة لنظام التشغيل Android" 4.9 و4.14 و4.19).
- يجب تضمين تصحيحات دعم PIDFD (تتوفر عمليات النقل السابقة في 4.9 و4.14 و4.19 من نواة Android الشائعة).
- بالنسبة إلى الأجهزة ذات ذاكرة وصول عشوائي منخفضة، يجب تضمين مجموعات cgroup للذاكرة.
يجب تجميع النواة باستخدام إعدادات الضبط التالية:
CONFIG_PSI=y
ضبط lmkd في Android 11
تتيح استراتيجية تحرير الذاكرة في Android 11 استخدام أداة التحكّم في الأداء والإعدادات التلقائية المدرَجة أدناه. تعمل هذه الميزات على كل من الأجهزة عالية الأداء وذات ذاكرة الوصول العشوائي المنخفضة.
الخاصية | استخدام | تلقائي | |
---|---|---|---|
أداء مرتفع | ذاكرة وصول عشوائي منخفضة | ||
ro.lmk.psi_partial_stall_ms |
الحدّ الأدنى لتوقف PSI الجزئي، بالمللي ثانية، لعرض إشعار انخفاض الذاكرة. إذا كان الجهاز يتلقّى إشعارات بشأن ضغط الذاكرة بعد فوات الأوان، يمكنك خفض هذه القيمة لعرض الإشعارات في وقت أبكر. إذا كانت إشعارات الضغط على الذاكرة تظهر بدون داعٍ، يمكنك زيادة هذه القيمة لجعل الجهاز أقل حساسية للضوضاء. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
الحدّ الكامل لتوقُّف PSI، بالكيلوميلّي ثانية، لتشغيل إشعارات الذاكرة الحرجة إذا كان الجهاز يتلقّى إشعارات الضغط الحر بالذاكرة متأخرة جدًا، يمكنك تقليل هذه القيمة لتشغيل إشعارات سابقة. إذا كانت إشعارات الضغط الشديد على الذاكرة تُرسَل بدون داعٍ، يمكنك زيادة هذه القيمة لجعل الجهاز أقل حساسية terhadap الضوضاء. | 700 |
|
ro.lmk.thrashing_limit |
الحد الأقصى لعدد عمليات إعادة ضبط مجموعة العمل كنسبة مئوية من إجمالي حجم ذاكرة التخزين المؤقت للصفحات المستندة إلى الملفات تعني حالات تعذُّر إعادة تحميل مجموعة العمل التي تتجاوز هذه القيمة أنّ النظام يُعدّ ذاكرة التخزين المؤقت للصفحات غير فعّالة. إذا كان أداء الجهاز يتأثر أثناء الضغط على الذاكرة، عليك خفض القيمة للحد من التبديل العشوائي للعمليات. إذا تم إيقاف أداء الجهاز بدون داعٍ لأسباب تتعلّق بالأعطال، يمكنك زيادة القيمة لإتاحة مزيد من الأعطال. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
انحدار حدّ الانهيار المعبَّر عنه كنسبة مئوية من الحدّ الأصلي المستخدَم لخفض الحدّ عندما لا يتم استرداد النظام، حتى بعد قتل العملية إذا أدّت عمليات القتل المتكرّرة إلى عمليات قتل غير ضرورية، يمكنك خفض القيمة. إذا كانت الاستجابة للاشتباك المستمر بعد عملية القتل بطيئة جدًا، يمكنك زيادة القيمة. | 10 |
50 |
ro.lmk.swap_util_max |
الحد الأقصى للذاكرة التي تم تبديلها كنسبة مئوية من إجمالي
الذاكرة القابلة للتبديل وعندما تتجاوز الذاكرة المتبادلة هذا الحد، يعني ذلك أنّ
النظام بدّل معظم ذاكرته القابلة للتبديل وما زال تحت الضغط.
يمكن أن يحدث ذلك عندما تؤدي عمليات التخصيص غير القابلة للاستبدال إلى زيادة في استخدام ملف تعريف الذاكرة
، ولا يمكن تخفيف هذا الضغط من خلال الاستبدال لأنّ معظم ملف تعريف الذاكرة
القابل للاستبدال قد تم استبداله. القيمة التلقائية هي 100، ما يؤدي إلى
إيقاف هذا التحقّق بشكل فعّال. إذا تأثّر أداء الجهاز أثناء
الضغط على الذاكرة عندما يكون استخدام مساحة التخزين المؤقت مرتفعًا ومستوى مساحة التخزين المؤقت المتاحة
لا ينخفض إلى ro.lmk.swap_free_low_percentage ، يمكنك خفض
القيمة للحد من استخدام مساحة التخزين المؤقت. |
100 |
100 |
تعمل مقابض الضبط القديمة التالية أيضًا مع استراتيجية القتل الجديدة.
الخاصية | استخدام | تلقائي | |
---|---|---|---|
أداء مرتفع | ذاكرة وصول عشوائي منخفضة | ||
ro.lmk.swap_free_low_percentage |
مستوى مساحة التخزين المؤقت المتاحة كنسبة مئوية من إجمالي مساحة التخزين المؤقت يستخدم الإجراء `lmkd` هذه القيمة كحدّ أدنى لتحديد الحالات التي يكون فيها النظام بحاجة إلى مساحة ملف التماثيل. إذا تم إغلاق "lmkd" عندما تكون هناك مساحة كبيرة جدًا في مساحة التخزين المؤقت، يمكنك خفض النسبة المئوية. إذا حدثت عمليات قتل lmkd بعد فوات الأوان، ما يسمح بحدوث عمليات قتل OOM ، عليك زيادة النسبة المئوية. | 20 |
10 |
ro.lmk.debug |
يؤدي ذلك إلى تفعيل سجلّات تصحيح أخطاء lmkd. فعِّل تصحيح الأخطاء أثناء عملية الضبط. | false |