شيطان الذاكرة المنخفض القاتل

تراقب عملية Android low memory killer ( lmkd ) حالة الذاكرة لنظام Android قيد التشغيل وتتفاعل مع ضغط الذاكرة المرتفع عن طريق قتل العمليات الأقل أهمية للحفاظ على أداء النظام عند مستويات مقبولة.

حول ضغط الذاكرة

قد يواجه نظام Android الذي يقوم بتشغيل عمليات متعددة على التوازي مواقف عندما يتم استنفاد ذاكرة النظام والعمليات التي تتطلب تجربة ذاكرة أكثر تأخيرات ملحوظة. يتطلب ضغط الذاكرة ، وهو الحالة التي يكون فيها النظام يعاني من نقص في الذاكرة ، من Android تحرير الذاكرة (لتخفيف الضغط) عن طريق اختناق أو قتل العمليات غير المهمة ، وطلب العمليات لتحرير الموارد المخزنة مؤقتًا غير الهامة ، وما إلى ذلك.

تاريخيًا ، كان Android يراقب ضغط ذاكرة النظام باستخدام برنامج تشغيل In-kernel Low Memory killer (LMK) ، وهي آلية صارمة تعتمد على القيم المشفرة. اعتبارًا من kernel 4.12 ، تمت إزالة برنامج تشغيل LMK من نواة المنبع وتقوم مساحة المستخدمين lmkd بمراقبة الذاكرة ومهام قتل العمليات.

معلومات توقف الضغط

يدعم Android 10 والإصدارات الأحدث وضع lmkd الجديد الذي يستخدم شاشات معلومات lmkd ضغط kernel (PSI) لاكتشاف ضغط الذاكرة. مجموعة التصحيح PSI في نواة المنبع (backported إلى 4.9 و 4.14 نواة) تقيس مقدار الوقت الذي تتأخر فيه المهام نتيجة لنقص الذاكرة. نظرًا لأن هذه التأخيرات تؤثر بشكل مباشر على تجربة المستخدم ، فإنها تمثل مقياسًا مناسبًا لتحديد شدة ضغط الذاكرة. تتضمن النواة lmkd أيضًا أجهزة مراقبة PSI التي تسمح لعمليات مساحة المستخدمين المميزة (مثل lmkd ) بتحديد عتبات هذه التأخيرات والاشتراك في الأحداث من النواة عند اختراق عتبة.

تراقب PSI مقابل إشارات vmpressure

نظرًا لأن إشارات vmpressure (التي يتم إنشاؤها بواسطة kernel للكشف عن ضغط الذاكرة واستخدامها بواسطة lmkd ) غالبًا ما تتضمن العديد من الإيجابيات الخاطئة ، يجب على lmkd إجراء تصفية لتحديد ما إذا كانت الذاكرة تحت ضغط حقيقي. ينتج عن هذا lmkd lmkd غير ضرورية واستخدام موارد حسابية إضافية. يؤدي استخدام أجهزة مراقبة PSI إلى اكتشاف ضغط الذاكرة بشكل أكثر دقة ويقلل من عبء التصفية.

استخدام شاشات PSI

لاستخدام شاشات PSI بدلاً من أحداث vmpressure ، قم بتكوين خاصية ro.lmk.use_psi . القيمة الافتراضية هي true ، مما يجعل شاشات PSI هي الآلية الافتراضية لاكتشاف ضغط الذاكرة لـ lmkd . نظرًا لأن شاشات PSI تتطلب دعم kernel ، يجب أن تتضمن kernel تصحيحات PSI backport وأن يتم تجميعها مع تمكين دعم PSI ( CONFIG_PSI=y ).

عيوب برنامج تشغيل In-kernel LMK

يعمل Android على إهمال برنامج تشغيل LMK نظرًا لعدد من المشكلات ، بما في ذلك:

  • كان لابد من ضبط الأجهزة ذات ذاكرة الوصول العشوائي المنخفضة بقوة ، وحتى في هذه الحالة سيكون أداءها ضعيفًا في أحمال العمل مع ذاكرة تخزين مؤقت كبيرة نشطة مدعومة من الملفات. أدى الأداء الضعيف إلى الضرب وعدم القتل.
  • اعتمد برنامج تشغيل نواة LMK على حدود الذاكرة الحرة ، مع عدم وجود مقياس يعتمد على ضغط الذاكرة.
  • بسبب صلابة التصميم ، غالبًا ما يقوم الشركاء بتخصيص برنامج التشغيل بحيث يعمل على أجهزتهم.
  • تم ربط سائق LMK بواجهة برمجة تطبيقات تقلص الألواح ، والتي لم يتم تصميمها للعمليات الثقيلة مثل البحث عن الأهداف وقتلها ، مما أدى إلى إبطاء عملية vmscan .

مساحة المستخدمين lmkd

تنفذ مساحة المستخدمين lmkd نفس الوظيفة التي يقوم بها برنامج التشغيل داخل النواة ولكنها تستخدم آليات النواة الحالية لاكتشاف وتقدير ضغط الذاكرة. تتضمن هذه الآليات استخدام أحداث vmpressure المُنشأة من kernel أو أجهزة مراقبة ضغط المعلومات (PSI) للحصول على إشعارات حول مستويات ضغط الذاكرة ، واستخدام ميزات مجموعة الذاكرة للحد من موارد الذاكرة المخصصة لكل عملية بناءً على أهمية العملية.

باستخدام مساحة المستخدمين lmkd في Android 10

في Android 9 والإصدارات الأحدث ، lmkd تنشيط مساحة المستخدمين lmkd إذا لم يتم اكتشاف برنامج تشغيل LMK داخل kernel. نظرًا لأن مساحة المستخدمين lmkd تتطلب دعم kernel لمجموعات cgroups للذاكرة ، يجب تجميع kernel باستخدام إعدادات التكوين التالية:

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

اقتل الاستراتيجيات

lmkd يدعم استراتيجيات القتل على أساس أحداث vmpressure أو شاشات PSI وشدتها وتلميحات أخرى مثل استخدام المبادلة. تختلف استراتيجيات القتل بين الأجهزة ذات الذاكرة المنخفضة والأجهزة عالية الأداء:

  • في الأجهزة ذات الذاكرة المنخفضة ، يجب أن يتحمل النظام ضغط ذاكرة أعلى كطريقة تشغيل عادية.
  • في الأجهزة عالية الأداء ، يجب النظر إلى ضغط الذاكرة على أنه وضع غير طبيعي ويتم إصلاحه قبل أن يؤثر على الأداء العام.

يمكنك تكوين استراتيجية القتل باستخدام خاصية ro.config.low_ram (لمزيد من التفاصيل ، راجع تكوين ذاكرة الوصول العشوائي المنخفضة ).

يدعم موقع lmkd أيضًا lmkd يتخذ فيه قرارات القتل باستخدام نفس الاستراتيجيات مثل برنامج التشغيل in-kernel LMK (أي الذاكرة الخالية وحدود ذاكرة التخزين المؤقت للملفات). لتمكين الوضع القديم ، ro.lmk.use_minfree_levels خاصية ro.lmk.use_minfree_levels على true .

تكوين lmkd

قم بتكوين lmkd لجهاز معين باستخدام الخصائص التالية.

ملكية يستخدم تقصير
ro.config.low_ram حدد ما إذا كان الجهاز ذو ذاكرة وصول عشوائي منخفضة أو جهاز عالي الأداء. false
ro.lmk.use_psi استخدم شاشات PSI (بدلاً من أحداث vmpressure ). true
ro.lmk.use_minfree_levels استخدم الذاكرة الفارغة وعتبات ذاكرة التخزين المؤقت للملفات لاتخاذ قرارات إنهاء العملية (أي مطابقة وظائف برنامج التشغيل in-kernel LMK). 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 الذي تمت ترقية المستوى mem_pressure لأن النظام يقوم بتبديل أكثر من اللازم. 100
(معاق)
ro.lmk.downgrade_pressure الحد الأدنى من mem_pressure الذي يتم vmpressure تجاهل حدث vmpressure ذاكرة خالية كافية. 100
(معاق)
ro.lmk.kill_heaviest_task اقتل أثقل مهمة مؤهلة (أفضل قرار) مقابل أي مهمة مؤهلة (قرار سريع). true
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 لمستويات استخدام موارد الذاكرة lmkd عليها لمنع تجويع الذاكرة وتدهور الأداء. تحل استراتيجية القتل هذه محل الاستراتيجيات السابقة ويمكن استخدامها على كل من الأجهزة عالية الأداء ومنخفضة ذاكرة الوصول العشوائي (Android Go).

متطلبات Kernel

بالنسبة لأجهزة Android 11 ، يتطلب lmkd ميزات kernel التالية:

  • قم بتضمين تصحيحات PSI وتمكين PSI (المنافذ الخلفية المتوفرة في نواة Android الشائعة 4.9 و 4.14 و 4.19).
  • قم بتضمين تصحيحات دعم PIDFD (المنافذ الخلفية المتوفرة في نواة Android الشائعة 4.9 و 4.14 و 4.19).
  • بالنسبة للأجهزة ذات ذاكرة الوصول العشوائي المنخفضة ، قم بتضمين مجموعات ذاكرة التخزين.

يجب تجميع النواة باستخدام إعدادات التكوين التالية:

CONFIG_PSI=y

تكوين lmkd في Android 11

تدعم إستراتيجية قتل الذاكرة في Android 11 مفاتيح التوليف والإعدادات الافتراضية المدرجة أدناه. تعمل هذه الميزات على كل من الأجهزة عالية الأداء ومنخفضة ذاكرة الوصول العشوائي.

ملكية يستخدم تقصير
أداء عالي ذاكرة وصول عشوائي منخفضة
ro.lmk.psi_partial_stall_ms عتبة التوقف الجزئي لـ PSI ، بالمللي ثانية ، لتشغيل إشعار انخفاض الذاكرة. إذا تلقى الجهاز إشعارات ضغط الذاكرة في وقت متأخر جدًا ، فقم بتقليل هذه القيمة لتشغيل إشعارات سابقة. إذا تم تشغيل إشعارات ضغط الذاكرة دون داع ، فقم بزيادة هذه القيمة لجعل الجهاز أقل حساسية للضوضاء. 70 200
ro.lmk.psi_complete_stall_ms حد توقف PSI الكامل ، بالمللي ثانية ، لتشغيل إشعارات الذاكرة الهامة. إذا تلقى الجهاز إشعارات ضغط الذاكرة المهمة في وقت متأخر جدًا ، فقم بتقليل هذه القيمة لتشغيل إشعارات سابقة. إذا تم تشغيل إشعارات ضغط الذاكرة الحرجة دون داع ، فقم بزيادة هذه القيمة لجعل الجهاز أقل حساسية للضوضاء. 700
ro.lmk.thrashing_limit الحد الأقصى لمقدار إعادة تعيين مجموعات العمل كنسبة مئوية من إجمالي حجم الصفحة المدعومة من الملف. إعادة السداد لمجموعة العمل أعلى من هذه القيمة تعني أن النظام يُنظر إليه على أنه يتفوق على pagecache. إذا تأثر أداء الجهاز أثناء ضغط الذاكرة ، فقم بتقليل القيمة للحد من الاصطدام. إذا تم إيقاف أداء الجهاز دون داع لأسباب تعثرية ، فقم بزيادة القيمة للسماح بمزيد من الضربات. 100 30
ro.lmk.thrashing_limit_decay يتم التعبير عن انحلال عتبة الضرب كنسبة مئوية من الحد الأصلي المستخدم لخفض العتبة عندما لا يتعافى النظام ، حتى بعد القتل. إذا نتج عن الضرب المستمر عمليات قتل غير ضرورية ، فقم بتقليل القيمة. إذا كانت الاستجابة للهجوم المستمر بعد القتل بطيئة جدًا ، فقم بزيادة القيمة. 10 50
ro.lmk.swap_util_max الحد الأقصى لمقدار الذاكرة المبادلة كنسبة مئوية من إجمالي الذاكرة القابلة للتبديل. عندما تنمو الذاكرة المبادلة فوق هذا الحد ، فهذا يعني أن النظام قام بتبديل معظم ذاكرته القابلة للتبديل ولا يزال تحت الضغط. يمكن أن يحدث هذا عندما تولد عمليات التخصيص غير القابلة للتبديل ضغطًا على الذاكرة لا يمكن تخفيفه عن طريق التبديل لأن معظم الذاكرة القابلة للتبديل قد تم تبديلها بالفعل. القيمة الافتراضية هي 100 ، مما يؤدي إلى تعطيل هذا الفحص بشكل فعال. إذا تأثر أداء الجهاز أثناء ضغط الذاكرة أثناء استخدام المبادلة عالية ولم ينخفض ​​مستوى التبديل المجاني إلى ro.lmk.swap_free_low_percentage ، 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