على نظام Android الأساسي، يحاول النظام استخدام أكبر قدر ممكن من ذاكرة النظام (ذاكرة الوصول العشوائي) ويُجري عمليات تحسين مختلفة للذاكرة من أجل توفير مساحة عند الحاجة. يمكن أن تؤثر عمليات التحسين هذه سلبًا في لعبتك، إما من خلال إبطائها أو إيقافها تمامًا. يمكنك الاطّلاع على مزيد من المعلومات عن عمليات التحسين هذه في موضوع توزيع الذاكرة بين العمليات.
توضّح هذه الصفحة الخطوات التي يمكنك اتّخاذها لتجنُّب الظروف التي تؤدي إلى نقص الذاكرة وتؤثر في لعبتك.
الردّ على onTrimMemory()
يستخدم النظام
onTrimMemory()
لإشعار تطبيقك بأحداث مراحل النشاط التي تمثّل فرصة جيدة لتطبيقك من أجل تقليل استخدام الذاكرة طوعًا وتجنُّب إيقافه من خلال
أداة إغلاق التطبيقات بسبب نقص الذاكرة (LMK)
لتحرير الذاكرة لاستخدامها في تطبيقات أخرى.
إذا تم إيقاف تطبيقك في الخلفية، سيواجه المستخدم عملية بدء تشغيل بطيئة في المرة التالية التي يفتح فيها تطبيقك على البارد. من غير المرجّح أن يتم إيقاف التطبيقات التي تقلّل من استخدامها للذاكرة عند الانتقال إلى الخلفية.
عند الردّ على أحداث تقليل الذاكرة، من الأفضل تحرير عمليات تخصيص الذاكرة الكبيرة التي لا تكون مطلوبة على الفور ويمكن إعادة إنشائها عند الطلب. على
سبيل المثال، إذا كان تطبيقك يتضمّن ذاكرة تخزين مؤقتة للصور النقطية التي تم فك ضغطها من صور مضغوطة مخزّنة محليًا، فمن المستحسن غالبًا تقليل حجم ذاكرة التخزين المؤقتة هذه أو إزالتها استجابةً للحدث
TRIM_MEMORY_UI_HIDDEN.
Kotlin
class MainActivity : AppCompatActivity(), ComponentCallbacks2 { override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { public void onTrimMemory(int level) { switch (level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } } }
التعامل بحذر مع ميزانيات الذاكرة
يجب التعامل بحذر مع ميزانية الذاكرة لتجنُّب نقص الذاكرة. في ما يلي بعض الجوانب التي يجب أخذها في الاعتبار:
- حجم ذاكرة الوصول العشوائي المادية: غالبًا ما تستخدم الألعاب ما بين رُبع ونصف مقدار ذاكرة الوصول العشوائي المادية على الجهاز.
- الحد الأقصى لحجم zRAM: يعني توفّر المزيد من zRAM أنّ اللعبة قد يكون لديها المزيد من الذاكرة
لتخصيصها. يمكن أن يختلف هذا المقدار استنادًا إلى الجهاز. ابحث عن
SwapTotalفي/proc/meminfoللعثور على هذه القيمة. - استخدام نظام التشغيل للذاكرة: الأجهزة التي تخصص المزيد من ذاكرة الوصول العشوائي لعمليات النظام تترك ذاكرة أقل للعبتك. يوقف النظام عملية لعبتك قبل إيقاف عمليات النظام.
- استخدام الذاكرة للتطبيقات المثبَّتة: اختبِر لعبتك على الأجهزة التي تم تثبيت العديد من التطبيقات عليها. تحتاج وسائل التواصل الاجتماعي وتطبيقات المحادثة إلى التشغيل باستمرار وتؤثر في مقدار الذاكرة المتاحة.
إذا لم تتمكّن من الالتزام بميزانية ذاكرة حذرة، اتّبِع نهجًا أكثر مرونة. إذا واجه النظام مشاكل نقص الذاكرة، قلِّل مقدار الذاكرة التي تستخدمها اللعبة. على سبيل المثال، خصِّص مواد عرض ذات دقة أقل أو خزِّن عددًا أقل من التظليلات استجابةً للحدث onTrimMemory(). يتطلب هذا النهج الديناميكي لتخصيص الذاكرة المزيد من العمل من المطوّر، لا سيما في مرحلة تصميم اللعبة.
تجنُّب الاحتدام
يحدث الاحتدام عندما تكون الذاكرة المتاحة منخفضة، ولكن ليس منخفضة بما يكفي لإيقاف اللعبة.
في هذه الحالة، استردّت kswapd صفحات لا تزال اللعبة بحاجة إليها، لذا تحاول إعادة تحميل الصفحات من الذاكرة. لا تتوفّر مساحة كافية، لذا تستمر الصفحات في التبديل (التبديل المستمر).
يرصد تتبُّع النظام هذه الحالة كسلسلة تعليمات
يتم فيها تشغيل kswapd باستمرار.
من أعراض الاحتدام أوقات عرض اللقطة الطويلة، ربما ثانية واحدة أو أكثر. قلِّل من استهلاك اللعبة للذاكرة لحلّ هذه الحالة.
استخدام الأدوات المتاحة
يتضمّن Android مجموعة من الأدوات التي تساعد في فهم كيفية إدارة النظام للذاكرة.
Meminfo
تجمع هذه الأداة إحصاءات الذاكرة لعرض مقدار ذاكرة PSS التي تم تخصيصها والفئات التي تم استخدامها من أجلها.
يمكنك طباعة إحصاءات meminfo بإحدى الطريقتَين التاليتَين:
- استخدِم الأمر
adb shell dumpsys meminfo package-name. - استخدِم طلب
MemoryInfoمن Android Debug API.
تعرض إحصاءات PrivateDirty مقدار ذاكرة الوصول العشوائي داخل العملية التي لا يمكن نقلها إلى القرص والتي لا تتم مشاركتها
مع أي عمليات أخرى. يصبح الجزء الأكبر من هذا المقدار متاحًا للنظام عند إيقاف هذه العملية.
نقاط تتبُّع الذاكرة
تتتبّع نقاط تتبُّع الذاكرة مقدار ذاكرة RSS التي تستخدمها لعبتك. إنّ حساب استخدام ذاكرة RSS أسرع بكثير من حساب استخدام ذاكرة PSS. بما أنّ حساب ذاكرة RSS أسرع، فإنّها تعرض دقة أفضل للتغييرات في حجم الذاكرة من أجل قياسات أكثر دقة لاستخدام الذاكرة القصوى. لذلك، من الأسهل ملاحظة الارتفاعات التي قد تؤدي إلى نقص الذاكرة في اللعبة.
Perfetto والآثار الطويلة
Perfetto هي مجموعة من الأدوات لجمع معلومات الأداء والذاكرة على جهاز وعرضها في واجهة مستخدم مستندة إلى الويب. تتيح لك هذه الأدوات تتبُّع الآثار الطويلة بشكل عشوائي حتى تتمكّن من الاطّلاع على كيفية تغيّر ذاكرة RSS بمرور الوقت. يمكنك أيضًا إجراء طلبات بحث بلغة SQL على البيانات التي تنتجها للمعالجة بلا إنترنت. فعِّل الآثار الطويلة من الـ تطبيق "تتبُّع النظام". تأكَّد من تفعيل فئة الـ memory:Memory للتتبُّع. للحصول على أدوات مخصّصة لتتبُّع الذاكرة في مرحلتَي التطوير والاختبار، يمكنك أيضًا استخدام (إصدار تجريبي)heapprofd API.
heapprofd
heapprofd هي أداة لتتبُّع الذاكرة تشكّل جزءًا من Perfetto. يمكن أن تساعدك هذه الأداة في العثور على تسرّبات الذاكرة من خلال عرض مكان تخصيص الذاكرة باستخدام malloc. يمكن بدء heapprofd باستخدام نص برمجي بلغة Python، وبما أنّ الأداة لا تستهلك الكثير من الموارد، فإنّها لا تؤثر في الأداء مثل الأدوات الأخرى، مثل Malloc Debug.
bugreport
bugreport هي أداة تسجيل لمعرفة ما إذا كانت لعبتك قد تعطّلت بسبب نقص الذاكرة أم لا. تكون نتائج الأداة أكثر تفصيلاً بكثير من استخدام logcat. تكون هذه الأداة مفيدة لتصحيح أخطاء الذاكرة لأنّها توضّح ما إذا كانت لعبتك قد تعطّلت بسبب نقص الذاكرة أو إذا تم إيقافها من خلال أداة إغلاق التطبيقات بسبب نقص الذاكرة (LMK).
لمزيد من المعلومات، يُرجى الاطّلاع على مقالة التقاط تقارير الأخطاء وقراءتها.