فحص استخدام الذاكرة في تطبيقك باستخدام "أداة تحليل الذاكرة"

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

لفتح Memory Profiler (أداة تحليل الذاكرة)، اتبع الخطوات التالية:

  1. انقر على عرض > Windows > أداة التحليل (يمكنك أيضًا النقر على الملف الشخصي في شريط الأدوات).
  2. اختَر عملية الجهاز والتطبيق التي تريد تحليلها من شريط أدوات الملف الشخصي على Android. إذا وصّلت جهازًا باستخدام USB ولم يظهر لك هذا الخيار، تأكَّد من تفعيل خيار "تصحيح أخطاء الجهاز عبر USB".
  3. انقر في أي مكان في المخطط الزمني MEMORY لفتح محلّل الذاكرة.

بدلاً من ذلك، يمكنك فحص ذاكرة التطبيق من سطر الأوامر باستخدام dumpsys، وكذلك الاطّلاع على أحداث GC في logcat.

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

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

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

للمساعدة في منع هذه المشكلات، يجب استخدام محلّل الذاكرة لإجراء ما يلي:

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

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

نظرة عامة على محلّل الذاكرة

عند فتح "محلل الذاكرة" لأول مرة، سيظهر لك مخطط زمني تفصيلي لاستخدام الذاكرة في تطبيقك والوصول إلى الأدوات اللازمة لفرض جمع البيانات غير المرغوب فيها، والتقاط نَسْخ للذاكرة، وتسجيل عمليات تخصيص الذاكرة.

الشكل 1. محلّل الذاكرة

كما هو موضح في الشكل 1، تتضمن طريقة العرض الافتراضية لمحلِّل الذاكرة ما يلي:

  1. زر لفرض حدث جمع البيانات غير المرغوب فيها.
  2. زر لالتقاط نَسْخ للذاكرة

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

  3. قائمة منسدلة لتحديد معدّل تسجيل المحلل لعمليات تخصيص الذاكرة قد يساعدك تحديد الخيار المناسب في تحسين أداء التطبيق أثناء إنشاء الملفات التعريفية.
  4. أزرار لتكبير المخطط الزمني أو تصغيره
  5. زر للانتقال إلى بيانات الذاكرة المباشرة
  6. المخطط الزمني للحدث الذي يعرض حالات النشاط وأحداث إدخال المستخدمين وأحداث تدوير الشاشة.
  7. المخطط الزمني لاستخدام الذاكرة، والذي يتضمّن ما يلي:
    • رسم بياني مكدّس لمقدار الذاكرة التي يتم استخدامها في كل فئة ذاكرة، كما هو موضّح في المحور y على اليسار ومفتاح اللون في الأعلى.
    • يشير الخط المتقطع إلى عدد العناصر المخصّصة، كما هو موضّح في المحور y على اليمين.
    • رمز لكل حدث من أحداث جمع البيانات غير المرغوب فيها

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

  • المخطط الزمني للحدث
  • عدد العناصر المخصّصة
  • فعّاليات جمع القمامة

في نظام التشغيل Android 8.0 والإصدارات الأحدث، يتم دائمًا تفعيل التحليل المتقدم للتطبيقات التي يمكن تصحيح الأخطاء فيها.

طريقة احتساب الذاكرة

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

الشكل 2. تشير وسيلة إيضاح عدد الذاكرة في الجزء العلوي من محلل الذاكرة

الفئات في عدد الذكريات هي كما يلي:

  • Java: الذاكرة من العناصر التي تم تخصيصها من رمز Java أو رمز Kotlin.
  • الأصلي: ذاكرة من العناصر التي تم تخصيصها من خلال رمز C أو C++.

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

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

  • حزمة التخزين: الذاكرة التي تستخدمها كل من الحزم الأصلية وحزمة Java في تطبيقك. يتعلق هذا عادةً بعدد سلاسل المحادثات التي يشغلها تطبيقك.

  • الرمز: الذاكرة التي يستخدمها تطبيقك للرموز البرمجية والموارد، مثل رمز بايت dex وكود dex المحسَّن أو المجمّع ومكتبات .so والخطوط.

  • الذاكرة الأخرى: الذاكرة المستخدمة في تطبيقك والتي لا يستطيع النظام تصنيفها.

  • التخصيص: عدد عناصر Java/Kotlin التي خصصها تطبيقك ولا يحتسب هذا العناصر المخصصة في C أو C++ .

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

عند المقارنة بعدد الذاكرة الذي تم قياسه في أداة "مراقبة Android" السابقة، يسجّل "محلل الذاكرة" الجديد ذكرياتك بطريقة مختلفة، فيبدو أنّ استخدام الذاكرة قد زاد الآن. يراقب محلل الذاكرة بعض الفئات الإضافية التي تزيد من الإجمالي، ولكن إذا كنت مهتمًا فقط بذاكرة Java لكمية الذاكرة، فيجب أن يكون رقم "Java" مشابهًا للقيمة من الأداة السابقة. على الرغم من أنّ رقم Java على الأرجح لا يتطابق تمامًا مع ما رأيته في Android Monitor، يمثّل الرقم الجديد جميع صفحات الذاكرة الفعلية التي تم تخصيصها ضِمن كومة JavaScript في تطبيقك منذ أن تم نقلها من Zygote. وهذا يوفر تمثيلاً دقيقًا لمقدار الذاكرة المادية التي يستخدمها تطبيقك بالفعل.

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

توضِّح لك عمليات تخصيص الذاكرة كيفية تخصيص كل عنصر من عناصر Java ومرجع JNI في ذاكرتك. على وجه التحديد، يمكن أن يعرض لك محلل الذاكرة ما يلي حول تخصيصات الكائنات:

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

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

عرض عمليات تخصيص Java في Memory Profiler

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

بعد اختيار منطقة من المخطط الزمني (أو عند الانتهاء من تسجيل جلسة باستخدام جهاز يعمل بالإصدار 7.1 من نظام التشغيل Android أو إصدار أقدم)، تظهر قائمة العناصر المخصّصة، ويتم تجميعها حسب اسم الفئة ومرتبة حسب عدد أعدادها.

لفحص سجلّ التخصيص، اتّبِع الخطوات التالية:

  1. تصفَّح القائمة للعثور على العناصر التي تتضمّن أعدادًا كبيرة غير معتادة من العناصر والتي قد تم تسريبها. للمساعدة في العثور على الفئات المعروفة، انقر على عنوان عمود اسم الفئة للترتيب أبجديًا. بعد ذلك، انقر على اسم صف. يظهر جزء عرض المثيل على اليسار، ويعرض كل مثيل من هذه الفئة، كما هو موضح في الشكل 3.
    • يمكنك بدلاً من ذلك تحديد موقع العناصر بسرعة من خلال النقر على رمز الفلترة أو عن طريق الضغط على Control+F (Command+F في نظام التشغيل Mac) وإدخال اسم فئة أو حزمة في حقل البحث. يمكنك أيضًا البحث حسب اسم الطريقة إذا اخترت ترتيب حسب المكالمات من القائمة المنسدلة. إذا كنت تريد استخدام تعبيرات عادية، ضَع علامة في المربّع بجانب Regex. ضَع علامة في المربّع بجانب مطابقة حالة الأحرف إذا كان طلب البحث حسّاسًا لحالة الأحرف.
  2. في جزء عرض المثيل، انقر على مثيل. تظهر علامة التبويب حزمة المكالمات أدناه، وتوضح أين تم تخصيص هذا المثيل وفي أي سلسلة محادثات.
  3. في علامة التبويب مجموعة استدعاءات المكالمات، انقر بزر الماوس الأيمن على أي سطر واختَر الانتقال إلى المصدر لفتح هذا الرمز في المحرِّر.

الشكل 3. تظهر التفاصيل حول كل كائن مخصص في عرض المثيل على اليسار

يمكنك استخدام القائمتين فوق قائمة العناصر المخصصة لاختيار كومة الذاكرة المؤقتة التي تريد فحصها وكيفية تنظيم البيانات.

من القائمة على اليمين، اختر كومة الذاكرة المؤقتة التي تريد فحصها:

  • التجميع التلقائي: عندما لا يحدِّد النظام كومة الذاكرة المؤقتة.
  • كومة الصورة: صورة تشغيل النظام التي تحتوي على فئات تم تحميلها مسبقًا أثناء وقت التشغيل. من المؤكّد أنّ التخصيصات هنا لن يتم نقلها أو إنهاءها على الإطلاق.
  • zygote heap: كومة النسخ عند الكتابة حيث تتم تجزئة عملية التطبيق في نظام Android.
  • كومة التطبيقات: الكومة الأساسية التي يخصص تطبيقك الذاكرة عليها
  • JNI Heap: المجموعة التي تعرض موضع تخصيص مراجع واجهة Java Native Interface (JNI) وإصدارها.

من القائمة على يسار الصفحة، اختَر كيفية ترتيب عمليات التوزيع:

  • الترتيب حسب الفئة: لتجميع جميع عمليات التخصيص استنادًا إلى اسم الفئة هذا هو الافتراضي.
  • ترتيب حسب الحزمة: تجمِّع جميع التخصيصات استنادًا إلى اسم الحزمة.
  • الترتيب حسب تسلسل المكالمات: يتم تجميع كل عمليات التخصيص في حزمة المكالمات المقابلة لها.

تحسين أداء التطبيق أثناء إنشاء الملفات التعريفية

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

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

الاطّلاع على مراجع JNI العامة

الواجهة الأصلية لـ Java (JNI) هي إطار عمل يسمح لكل من رمز Java والتعليمات البرمجية الأصلية بالاتصال ببعضهما البعض.

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

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

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

الشكل 4. الاطّلاع على مراجع JNI العالمية

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

لمزيد من المعلومات حول JNI، يمكنك الاطّلاع على نصائح JNI.

محلّل الذاكرة الأصلية

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

يتتبّع محلّل الذاكرة الأصلي عمليات تخصيص أو عمليّات تخصيص الكائنات في الرموز البرمجية الأصلية لفترة زمنية محدَّدة ويوفّر المعلومات التالية:

  • التخصيصات: عدد العناصر التي تمّ تخصيصها من خلال malloc() أو عامل التشغيل new خلال الفترة الزمنية المحدّدة
  • مواقع الصفقات: عدد العناصر التي تم نقلها عبر free() أو عامل تشغيل delete خلال الفترة الزمنية المحدّدة.
  • حجم التخصيصات: الحجم المجمّع بالبايت لجميع عمليات التخصيص خلال الفترة الزمنية المحدّدة.
  • حجم الصفقات: الحجم المجمَّع بالبايت من كل الذاكرة التي تم إخلاء جزء منها خلال الفترة الزمنية المحدّدة.
  • إجمالي العدد: القيمة في عمود التخصيصات مطروحًا منها القيمة في عمود الصفقات.
  • الحجم المتبقي: القيمة في عمود حجم التخصيصات مطروحًا منه القيمة في عمود حجم الصفقات.

محلّل الذاكرة الأصلية

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

زر تسجيل عمليات التخصيص الأصلية

في نظام التشغيل Android 9 والإصدارات الأقدم، لا يتوفّر خيار تسجيل عمليات التوزيع الأصلية.

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

لتغيير حجم العينة في محلّل الذاكرة الأصلية:

  1. اختر تشغيل > تعديل عمليات الضبط.
  2. اختَر وحدة التطبيق في اللوحة اليمنى.
  3. انقر على علامة التبويب التحليل، وأدخِل حجم العينة في الحقل المسمى الفاصل الزمني لأخذ عيّنات الذاكرة الأصلية (بالبايت).
  4. أنشئ تطبيقك وشغِّله من جديد.

تسجيل عملية تفريغ الذاكرة

يعرض نَسْخ الذاكرة العناصر في تطبيقك التي تستخدم الذاكرة في الوقت الذي تسجّل فيه نَسْخ الذاكرة. وخاصةً بعد جلسة مستخدم مطوّلة، يمكن أن يساعد تفريغ الذاكرة في تحديد تسرُّب الذاكرة من خلال عرض العناصر التي لا تزال في الذاكرة التي تعتقد أنّه يجب عدم توفّرها بعد الآن.

بعد تسجيل نَسْخ الذاكرة، يمكنك الاطّلاع على ما يلي:

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

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

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

الشكل 5. جارٍ عرض نَسْخ الذاكرة.

إذا أردت أن تكون أكثر دقة في ما يتعلق بوقت إنشاء ملف الذاكرة، يمكنك إنشاء نَسْخ ذاكرة في النقطة الحرجة من رمز التطبيق من خلال طلب الرمز dumpHprofData().

في قائمة الصفوف، يمكنك الاطّلاع على المعلومات التالية:

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

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

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

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

يمكنك استخدام القائمتين فوق قائمة العناصر المخصّصة لاختيار عمليات تفريغ الذاكرة التي تريد فحصها وكيفية تنظيم البيانات.

من القائمة على اليمين، اختر كومة الذاكرة المؤقتة التي تريد فحصها:

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

من القائمة على يسار الصفحة، اختَر كيفية ترتيب عمليات التوزيع:

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

يتم ترتيب القائمة حسب عمود الحجم المحتفظ به تلقائيًا. للفرز حسب القيم الموجودة في عمود مختلف، انقر فوق عنوان العمود.

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

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

الشكل 6. وتتم الإشارة إلى المدة المطلوبة لتسجيل نَسخ الذاكرة في المخطط الزمني

لفحص كومة الذاكرة المؤقتة، اتّبِع الخطوات التالية:

  1. تصفَّح القائمة للعثور على العناصر التي تتضمّن أعدادًا كبيرة غير معتادة من العناصر والتي قد تم تسريبها. للمساعدة في العثور على الفئات المعروفة، انقر على عنوان عمود اسم الفئة للترتيب أبجديًا. بعد ذلك، انقر على اسم صف. يظهر جزء عرض المثيل على اليسار، ويعرض كل مثيل من هذه الفئة، كما هو موضح في الشكل 6.
    • يمكنك بدلاً من ذلك تحديد موقع العناصر بسرعة من خلال النقر على رمز الفلترة أو عن طريق الضغط على Control+F (Command+F في نظام التشغيل Mac) وإدخال اسم فئة أو حزمة في حقل البحث. يمكنك أيضًا البحث حسب اسم الطريقة إذا اخترت ترتيب حسب المكالمات من القائمة المنسدلة. إذا كنت تريد استخدام تعبيرات عادية، ضَع علامة في المربّع بجانب Regex. ضَع علامة في المربّع بجانب مطابقة حالة الأحرف إذا كان طلب البحث حسّاسًا لحالة الأحرف.
  2. في جزء عرض المثيل، انقر على مثيل. تظهر علامة التبويب المراجع أدناه، وتعرض كل إشارة إلى ذلك الكائن.

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

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

في نَسْخ الذاكرة، ابحث عن تسرُّب الذاكرة الناتج عن أي مما يلي:

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

حفظ تفريغ الذاكرة كملف HPROF

بعد التقاط تفريغ للذاكرة، لا تظهر البيانات إلا في أداة Memory Profiler قيد التشغيل. عند الخروج من جلسة إنشاء الملفات التعريفية، لن يتم الاحتفاظ بنسخة احتياطية من البيانات. لذلك، إذا كنت تريد حفظه للمراجعة لاحقًا، عليك تصدير تفريغ الذاكرة إلى ملف HPROF. في الإصدار 3.1 من "استوديو Android" والإصدارات الأقدم، يظهر الزر تصدير الالتقاط إلى ملف على الجانب الأيمن من شريط الأدوات أسفل المخطط الزمني. في الإصدار 3.2 من "استوديو Android" والإصدارات الأحدث، يمكنك العثور على الزر تصدير نسخ الذاكرة على يسار كل إدخال نسخ الذاكرة ضمن لوحة الجلسات. في مربع الحوار تصدير باسم الذي يظهر، احفظ الملف بامتداد اسم الملف .hprof.

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

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

استيراد ملف تفريغ الذاكرة

لاستيراد ملف HPROF (.hprof)، انقر على بدء جلسة تحليل ملفات جديدة في جزء الجلسات، وحدد تحميل من الملف، ثم اختر الملف من متصفح الملفات.

يمكنك أيضًا استيراد ملف HPROF عن طريق سحبه من متصفح الملفات إلى نافذة المحرر.

رصد التسرُّب في محلّل الذاكرة

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

تشمل أنواع البيانات التي يعرضها الفلتر ما يلي:

  • دمت Activity مثيل ولكن لا تزال تتم الإشارة إليها.
  • مثيلات Fragment التي لا تحتوي على قيمة FragmentManager صالحة ولكن لا تزال تتم الإشارة إليها.

في بعض الحالات، مثل الحالات التالية، قد يعرض الفلتر نتائج إيجابية كاذبة:

  • تم إنشاء Fragment ولكن لم يتم استخدامها حتى الآن.
  • يتم تخزين Fragment مؤقتًا ولكن ليس كجزء من FragmentTransaction.

لاستخدام هذه الميزة، عليك أولاً التقاط نَسْخ للذاكرة أو استيراد ملف تفريغ الذاكرة إلى "استوديو Android". لعرض الأجزاء والأنشطة التي قد تؤدي إلى تسرّب الذاكرة، حدِّد مربّع الاختيار نشاط/تسرّب أجزاء في جزء تفريغ الذاكرة في أداة تحليل الذاكرة، كما هو موضّح في الشكل 7.

محلّل: رصد تسرُّب الذاكرة

الشكل 7. جارٍ فلترة نَسْخ الذاكرة بسبب تسرّب الذاكرة.

استخدام تقنيات تحليل الذاكرة

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

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

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

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