تخصيص الذاكرة بين العمليات

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

تناقش هذه الصفحة أساسيات كيفية تخصيص Android للذاكرة للنظام ولتطبيقات المستخدمين. كما يشرح كيفية تفاعل نظام التشغيل مع حالات انخفاض الذاكرة.

أنواع الذاكرة

تحتوي أجهزة Android على ثلاثة أنواع مختلفة من الذاكرة: ذاكرة الوصول العشوائي، وzRAM، ومساحة التخزين. لاحظ أن كل من وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسومات (GPU) تدخلان إلى نفس ذاكرة الوصول العشوائي (RAM).

أنواع الذاكرة

الشكل 1. أنواع الذاكرة - ذاكرة الوصول العشوائي، وzRAM، والتخزين

  • تعد ذاكرة الوصول العشوائي (RAM) أسرع نوع من الذاكرة، لكنها عادة ما تكون محدودة. تحتوي الأجهزة المتطورة عادةً على أكبر قدر من ذاكرة الوصول العشوائي (RAM).

  • zRAM هي قسم من ذاكرة الوصول العشوائي (RAM) يُستخدم كمساحة تبديل. يتم ضغط كل شيء عند وضعه في zRAM، ثم فك ضغطه عند نسخه من zRAM. يزداد حجم هذا الجزء من ذاكرة الوصول العشوائي أو يتقلص عند نقل الصفحات إلى zRAM أو إزالتها منه. ويمكن للشركات المصنّعة للأجهزة ضبط الحد الأقصى للحجم.

  • تحتوي مساحة التخزين على جميع البيانات الدائمة، مثل نظام الملفات ورمز العنصر المضمّن لجميع التطبيقات والمكتبات والنظام الأساسي. تحتوي مساحة التخزين على سعة أكبر بكثير من النوعين الآخرين من الذاكرة. في نظام Android، لا يتم استخدام التخزين كمساحة تبديل كما هو الحال في تطبيقات Linux الأخرى لأن الكتابة المتكررة يمكن أن تتسبب في تآكل هذه الذاكرة وتقصير عمر وسيط التخزين.

صفحات الذاكرة

يتم تقسيم ذاكرة الوصول العشوائي (RAM) إلى صفحات. يبلغ حجم كل صفحة عادةً 4 كيلوبايت من الذاكرة.

تُعتبر الصفحات مجانية أو مستعملة. الصفحات المجانية عبارة عن ذاكرة وصول عشوائي غير مستخدمة. والصفحات المستخدمة هي ذاكرة الوصول العشوائي التي يستخدمها النظام، ويتم تجميعها في الفئات التالية:

  • ذاكرة التخزين المؤقت: ذاكرة مدعومة بملف على مساحة التخزين (مثل رمز أو ملفات تم ربطها بالذاكرة). هناك نوعان من الذاكرة المخزّنة مؤقتًا:
    • خاص: مملوك من خلال عملية واحدة وليس مشترك
      • الحذف: نسخة غير معدلة من ملف على مساحة التخزين، يمكن حذفها من خلال kswapd لزيادة سعة الذاكرة الخالية
      • غير نظيف: نسخة معدّلة من الملف على مساحة التخزين، يمكن نقلها إلى zRAM أو ضغطها فيها بمقدار kswapd لزيادة الذاكرة الخالية
    • مشترَك: مستخدَمة في عمليات متعدّدة
      • الحذف: نسخة غير معدلة من الملف المتاح على مساحة التخزين، يمكن حذفها عن طريق kswapd لزيادة سعة الذاكرة الخالية
      • غير شامل: نسخة معدَّلة من الملف المحفوظ على مساحة التخزين، تسمح بكتابة التغييرات مرة أخرى في الملف المُخزَّن في مساحة التخزين لزيادة الذاكرة الفارغة عن طريق kswapd، أو الاستخدام الصريح لـ msync() أو munmap()
  • مجهول: الذاكرة ليست مدعومة من ملف على مساحة التخزين (على سبيل المثال، تم تخصيصها من قِبل mmap() مع مجموعة علامات MAP_ANONYMOUS)
    • البيانات غير النظيفة: يمكن نقلها/ضغطها في ذاكرة zRAM بنسبة kswapd لزيادة الذاكرة المجانية.

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

إدارة منخفضة للذاكرة

يشتمل Android على آليتين أساسيتين للتعامل مع مواقف انخفاض الذاكرة: البرنامج الخفي للتبديل بين النواة (kernel) والأداة القاتلة للذاكرة المنخفضة.

البرنامج الخفي لتبديل النواة

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

بإمكان kswapd استرداد الصفحات النظيفة من خلال حذفها لأنّها مدعومة بمساحة تخزين ولم يتم تعديلها. إذا حاولت إحدى العمليات معالجة صفحة نظيفة تم حذفها، فيقوم النظام بنسخ الصفحة من التخزين إلى ذاكرة الوصول العشوائي (RAM). وتُعرف هذه العملية باسم تقسيم الطلب على صفحات.

تم حذف الصفحة النظيفة من خلال الاحتفاظ بنسخة احتياطية من مساحة التخزين.

الشكل 2. تم حذف الصفحة النظيفة والمستندة إلى مساحة التخزين.

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

وإذا انخفض مقدار الذاكرة الخالية عن حد معين، يبدأ النظام في إيقاف العمليات.

تم نقل الصفحة غير النظيفة إلى zRAM وضغطها

الشكل 3. تم نقل الصفحة غير النظيفة إلى zRAM وضغطها

أداة قاتلة للذاكرة المنخفضة

في كثير من الأحيان، لا يمكن لنظام kswapd إخلاء مساحة كافية للنظام. في هذه الحالة، يستخدم النظام onTrimMemory() لإشعار أحد التطبيقات بأنّ الذاكرة أوشكت على النفاد وأنّه يجب أن يحدّ من تخصيصاته. إذا لم يكن ذلك كافيًا، تبدأ النواة في قتل العمليات لتحرير الذاكرة. كما أنه يستخدم أداة قاتلة الذاكرة (LMK) للقيام بذلك.

لتحديد العملية التي يجب إنهاؤها، يستخدم LMK تقييم "نفاد الذاكرة" الذي يُطلق عليه oom_adj_score لإعطاء الأولوية للعمليات الجارية. يتم قتل العمليات ذات النتيجة العالية أولاً. يتم أولاً إيقاف تطبيقات الخلفية بينما يتم إنهاء العمليات الخاصة بالنظام قبلها. يسرد الجدول التالي فئات نتائج LMK من المرتفع إلى الأدنى. سيتم قتل العناصر في الفئة الأعلى من الدرجات في الصف الأول أولاً:

عمليات Android، الحصول على أعلى النتائج

الشكل 4. عمليات Android، حيث يتم تسجيل أعلى النتائج ودرجات منخفضة في الأسفل

في ما يلي أوصاف للفئات المختلفة في الجدول أعلاه:

  • تطبيقات الخلفية: هي التطبيقات التي تم تشغيلها سابقًا ولكنها غير نشطة حاليًا. سيوقف LMK أولاً تطبيقات الخلفية بدءًا من التطبيق الذي يتضمن أعلى قيمة oom_adj_score.

  • التطبيق السابق: التطبيق الأخير في الخلفية الذي تم استخدامه مؤخرًا. ويحظى التطبيق السابق بأولوية أعلى (نتيجة أقل) من تطبيقات الخلفية لأنّه من المرجّح أن يبدِّل المستخدم إليه بدلاً من تطبيق واحد من تطبيقات الخلفية.

  • تطبيق Home: هذا هو تطبيق مشغّل التطبيقات. سيؤدي إيقاف الشاشة إلى اختفاء الخلفية.

  • الخدمات: يتم بدء الخدمات بواسطة التطبيقات وقد تتضمن المزامنة أو التحميل إلى السحابة الإلكترونية.

  • التطبيقات الملموسة: هي التطبيقات التي لا تعمل في المقدّمة والتي يلاحظها المستخدم بطريقة ما، مثل إجراء عملية بحث تعرض واجهة مستخدم صغيرة أو الاستماع إلى الموسيقى.

  • التطبيق الذي يعمل في المقدّمة: التطبيق المستخدَم حاليًا يبدو إيقاف التطبيق الذي يعمل في المقدّمة وكأنّه عطل في التطبيق قد يشير إلى المستخدم بحدوث خطأ ما في الجهاز.

  • دائمة (الخدمات): هذه هي الخدمات الأساسية للجهاز، مثل الاتصال الهاتفي وشبكة Wi-Fi.

  • النظام: عمليات النظام. عند إنهاء هذه العمليات، قد يبدو أن الهاتف قيد إعادة التشغيل.

  • مدمجة مع المحتوى: هي العمليات ذات المستوى المنخفض جدًا التي يستخدمها النظام (على سبيل المثال، kswapd).

يمكن للشركات المصنعة للأجهزة تغيير سلوك LMK.

جارٍ احتساب استهلاك الذاكرة

تتعقب النواة kernel جميع صفحات الذاكرة في النظام.

الصفحات التي تستخدمها عمليات مختلفة

الشكل 5. الصفحات التي تستخدمها عمليات مختلفة

عند تحديد مقدار الذاكرة التي يستخدمها أحد التطبيقات، يجب على النظام حساب الصفحات المشتركة. ستشارك التطبيقات التي يمكنها الوصول إلى الخدمة أو المكتبة نفسها صفحات الذاكرة. على سبيل المثال، قد تشترك "خدمات Google Play" وتطبيق لعبة في خدمة الموقع الجغرافي. هذا يجعل من الصعب تحديد مقدار الذاكرة التي تنتمي إلى الخدمة بشكل كبير مقابل كل تطبيق.

الصفحات التي يشاركها تطبيقان

الشكل 6. الصفحات التي يشاركها تطبيقان (في الوسط)

لتحديد مساحة الذاكرة لأحد التطبيقات، يمكن استخدام أي من المقاييس التالية:

  • حجم مجموعة المقيمين (RSS): عدد الصفحات المشترَكة وغير المشترَكة التي يستخدمها التطبيق
  • حجم المجموعة التناسبي (PSS): عدد الصفحات غير المشتركة التي يستخدمها التطبيق والتوزيع المتساوي للصفحات المشتركة (على سبيل المثال، إذا كانت ثلاث عمليات تشارك 3 ميغابايت، تحصل كل عملية على 1 ميغابايت في خدمة PSS)
  • حجم المجموعة الفريدة (USS): عدد الصفحات غير المشتركة التي يستخدمها التطبيق (لا يتم تضمين الصفحات المشتركة)

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

مراجع إضافية