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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • الحقول: يعرض جميع الحقول في هذا المثيل.
  • المراجع: يعرض كل مرجع للعنصر المميّز في علامة التبويب المثيل.
طرق العرض Instances وFields وReferences في نافذة أداة Heap Dump

رصد الصور النقطية المكرّرة

يمكنك أيضًا رصد الصور النقطية المتكرّرة في عرض "لقطة لأجزاء من الذاكرة" (Heap Dump) بدءًا من الإصدار الرابع من Android Studio Narwhal.

إليك كيفية العثور عليها:

  1. فتح علامة التبويب Profiler في "استوديو Android"
  2. انقر على لقطة لأجزاء من الذاكرة (أو تحليل استخدام الذاكرة) ثم انقر على "تسجيل" لأخذ لقطة لحالة الذاكرة الحالية في تطبيقك.
  3. ابحث في نتائج التحليل عن مثلث التحذير الأصفر ⚠️، الذي يستخدمه "استوديو Android" للإشارة إلى صور نقطية مكرّرة يتم تخزينها عدة مرات.
    • بدلاً من ذلك، انتقِل إلى عنوان أداة التحليل، واختَر الفلترة حسب: وحدِّد الإعداد صور نقطية مكرّرة.
  4. انقر على أي إدخال تم وضع علامة عليه لفتح لوحة معاينة الصورة النقطية، مما يتيح لك معرفة الصورة التي تكرر المخالفة بالضبط.
  5. استخدِم هذا التأكيد المرئي لتتبُّع منطق التحميل المتكرر في الرمز البرمجي وتنفيذ استراتيجية تخزين مؤقت أفضل.
ابحث عن صور نقطية مكرّرة باستخدام مثلّث التحذير الأصفر ⚠️.

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

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

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

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

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

تفعيل تسرُّب الذاكرة للاختبار

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

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

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

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

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

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

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

مراجع إضافية