التقاط نَسْخ للذاكرة

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

تصف هذه الصفحة الأدوات التي يوفّرها "استوديو Android" لجمع لقطات لأجزاء من الذاكرة وتحليلها. بدلاً من ذلك، يمكنك فحص ذاكرة تطبيقك من سطر الأوامر باستخدام dumpsys والاطّلاع أيضًا على أحداث جمع البيانات غير الضرورية (GC) في Logcat.

أهمية تحديد المشاكل في ذاكرة تطبيقك

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

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

للحصول على معلومات حول ممارسات البرمجة التي يمكن أن تقلّل من استخدام تطبيقك للذاكرة ، اطّلِع على مقالة إدارة ذاكرة تطبيقك.

نظرة عامة على لقطات أجزاء من الذاكرة

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

عرض "لقطة لأجزاء من الذاكرة" في "أداة تحديد المشاكل" في "استوديو Android"

تعرض قائمة الفئات المعلومات التالية:

  • عمليات التخصيص: عدد عمليات التخصيص في الذاكرة الرئيسية.
  • الحجم الأصلي: إجمالي حجم الذاكرة الأصلية التي يستخدمها نوع الكائن هذا (بال بايت). ستظهر لك الذاكرة هنا لبعض الكائنات التي تم تخصيصها في Java لأنّ Android يستخدم الذاكرة الأصلية لبعض فئات إطار العمل، مثل Bitmap.

  • الحجم السطحي: إجمالي حجم ذاكرة Java التي يستخدمها نوع الكائن هذا (بالبايت).

  • الحجم المحتفظ به: إجمالي حجم الذاكرة المحتفظ بها بسبب جميع مثيلات هذه الفئة (بالبايت).

استخدِم قائمة الذاكرة الرئيسية للفلترة حسب ذاكرة رئيسية معيّنة:

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

استخدِم القائمة المنسدلة "الترتيب" لاختيار كيفية ترتيب عمليات التخصيص:

  • الترتيب حسب الفئة (تلقائي): يجمّع جميع عمليات التخصيص استنادًا إلى اسم الفئة.
  • الترتيب حسب الحزمة: يجمّع جميع عمليات التخصيص استنادًا إلى اسم الحزمة.

استخدِم القائمة المنسدلة "الفئة" للفلترة حسب مجموعات الفئات:

  • جميع الفئات (تلقائي): يعرض جميع الفئات، بما في ذلك الفئات من المكتبات والتبعيات.
  • عرض تسرّبات الأنشطة/الأجزاء: يعرض الفئات التي تسبّب تسرّبات الذاكرة.
  • عرض فئات المشروع: يعرض الفئات التي يحدّدها مشروعك فقط.

انقر على اسم فئة لفتح لوحة المثيل. يتضمّن كل مثيل مدرَج ما يلي:

  • العمق: أقصر عدد من عمليات الانتقال من أي جذر لجمع البيانات غير الضرورية إلى المثيل المحدّد.
  • الحجم الأصلي: حجم هذا المثيل في الذاكرة الأصلية. لا يظهر هذا العمود إلا في Android 7.0 والإصدارات الأحدث.
  • الحجم السطحي: حجم هذا المثيل في ذاكرة Java.
  • الحجم المحتفظ به: حجم الذاكرة التي يتحكّم بها هذا المثيل (وفقًا لـ شجرة المتحكّم).

انقر على مثيل لعرض تفاصيل المثيل، بما في ذلك الحقول والمراجع. أنواع الحقول والمراجع الشائعة هي الأنواع المنظَّمة والمصفوفات وأنواع البيانات الأساسية في Java. انقر بزر الماوس الأيمن على حقل أو مرجع للانتقال إلى المثيل المرتبط أو السطر في رمز المصدر.

  • الحقول: يعرض جميع الحقول في هذا المثيل.
  • المراجع: يعرض كل مرجع للكائن المميَّز في علامة التبويب المثيل.
عروض المثيلات والحقول والمراجع في نافذة أداة "لقطة لأجزاء من الذاكرة".

العثور على تسرّبات الذاكرة

للفلترة بسرعة حسب الفئات التي قد تكون مرتبطة بتسرّبات الذاكرة، افتح القائمة المنسدلة "الفئة" واختَر عرض تسرّبات الأنشطة/الأجزاء. يعرض "استوديو Android" الفئات التي يعتقد أنّها تشير إلى تسرّبات الذاكرة لمثيلات Activity و Fragment في تطبيقك.

للبحث عن تسرّبات الذاكرة يدويًا بشكل أكبر، تصفَّح قوائم الفئات والمثيلات للعثور على الكائنات التي لها حجم محتفظ به كبير. ابحث عن تسرّبات الذاكرة الناتجة عن أي مما يلي:

  • المراجع الطويلة الأمد إلى Activity أو Context التي يمكن أن تسرّب الرسم البياني لتركيبة Compose المستضافة (مثل ComposeView والعناصر الفرعية القابلة للإنشاء).
  • تسرّب كائنات Jetpack Compose State (MutableState) أو عناصر التحكّم في الحالة أو تعبيرات لامدا التي تلتقط Context.
  • عدم تنظيف المستمعين أو المراقبين في كتلة onDispose من DisposableEffect.
  • الفئات الداخلية غير الثابتة، مثل Runnable، التي يمكن أن تحتوي على مثيل Activity.
  • ذاكرات التخزين المؤقت التي تحتفظ بالكائنات لفترة أطول من اللازم.

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

إحداث تسرّبات الذاكرة للاختبار

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

يمكنك أيضًا إحداث تسرّب الذاكرة بإحدى الطرق التالية:

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

تصدير تسجيل لقطة لأجزاء من الذاكرة واستيراده

يمكنك تصدير ملف لقطة لأجزاء من الذاكرة واستيراده من علامة التبويب التسجيلات السابقة في أداة تحديد المشاكل. يحفظ "استوديو Android" التسجيل كملف ‎.hprof.

بدلاً من ذلك، لاستخدام محلّل ملفات .hprof مختلف، مثل jhat، عليك تحويل ملف .hprof من تنسيق Android إلى تنسيق ملف .hprof Java SE. لتحويل تنسيق الملف، استخدِم أداة hprof-conv المتوفّرة في الدليل {android_sdk}/platform-tools/. شغِّل الأمر hprof-conv باستخدام وسيطتَين: اسم ملف ‎.hprof الأصلي والموقع الذي تريد كتابة ملف ‎.hprof المحوَّل فيه، بما في ذلك اسم ملف ‎.hprof الجديد. على سبيل المثال:

hprof-conv heap-original.hprof heap-converted.hprof

مراجع إضافية