برنامج خفي لقتل الذاكرة

إنّ البرنامج الخفي لاختراق الذاكرة المنخفض (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