أفضل ممارسات إدارة الذاكرة

يفترض هذا المستند أنّك اتّبعت إرشادات أفضل الممارسات لتطبيقات Android ضمن إدارة الذاكرة، مثل إدارة ذاكرة تطبيقك.

مقدمة

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

يوفّر لك هذا المستند بعض أفضل الممارسات للمساعدة في منع تسرُّب الذاكرة في الرمز البرمجي ورصده وحله. إذا جرّبت الطرق الموضَّحة في هذا المستند وتشتبه في حدوث تسرُّب للذاكرة في حِزم SDK، راجِع كيفية الإبلاغ عن مشاكل بشأن حِزم تطوير البرامج (SDK) من Google.

قبل التواصل مع فريق الدعم

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

منع تسرُّب الذاكرة

اتّبِع أفضل الممارسات التالية للمساعدة في تجنُّب بعض الأسباب الأكثر شيوعًا ل تسرُّب الذاكرة في الرموز البرمجية التي تستخدِم حِزم تطوير البرامج (SDK) من Google.

أفضل الممارسات لتطبيقات Android

تأكَّد من تنفيذ كلّ ما يلي في تطبيق Android:

  1. إلغاء حجز الموارد غير المستخدَمة
  2. إلغاء تسجيل المستمعين عندما لا يعودون مطلوبين
  3. إلغاء المهام عند عدم الحاجة إليها:
  4. إعادة توجيه طرق دورة الحياة لإلغاء حجز الموارد
  5. استخدام أحدث إصدارات حِزم تطوير البرامج (SDK)

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

إلغاء حجز الموارد غير المستخدَمة

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

إزالة مراجع GoogleMap القديمة في حِزم GeoSDK

من الأخطاء الشائعة أنّ GoogleMap يمكن أن يتسبب في تسرُّب الذاكرة إذا تم تخزينه مؤقتًا باستخدام NavigationView أو MapView. ترتبط GoogleMap بعلاقة 1 إلى 1 مع NavigationView أو MapView التي يتم استرجاعها منها. يجب ضمان عدم تخزين GoogleMap مؤقتًا أو إزالة المراجع عند استدعاء NavigationView#onDestroy أو MapView#onDestroy. إذا كنت تستخدم NavigationSupportFragment أو MapSupportFragment أو الجزء الخاص بك الذي يلتف حول هذه طرق العرض، يجب إصدار المرجع في Fragment#onDestroyView.

class NavFragment : SupportNavigationFragment() {

  var googleMap: GoogleMap?

  override fun onCreateView(
    inflater: LayoutInflater,
    parent: ViewGroup?,
    savedInstanceState: Bundle?,
  ): View  {
    super.onCreateView(inflater,parent,savedInstanceState)
    getMapAsync{map -> googleMap = map}
  }

  override fun onDestroyView() {
    googleMap = null
  }
}

إلغاء تسجيل المستمعين عند عدم الحاجة إليهم

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

على سبيل المثال، لنفترض أنّ تطبيقك يستخدم حزمة تطوير البرامج (SDK) لنظام التنقّل ويُطلِق أداة الاستماع التالية لرصد أحداث الوصول: addArrivalListener طريقة للاستماع إلى أحداث الوصول، ويجب أن يُطلِق أيضًا removeArrivalListener عندما لا يعود بحاجة إلى مراقبة أحداث الوصول.

var arrivalListener: Navigator.ArrivalListener? = null

fun registerNavigationListeners() {
  arrivalListener =
    Navigator.ArrivalListener {
      ...
    }
  navigator.addArrivalListener(arrivalListener)
}

override fun onDestroy() {
  navView.onDestroy()
  if (arrivalListener != null) {
    navigator.removeArrivalListener(arrivalListener)
  }

  ...
  super.onDestroy()
}

إلغاء المهام عندما لا تكون مطلوبة

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

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

إعادة توجيه طرق دورة الحياة لإصدار الموارد

إذا كان تطبيقك يستخدم "حزمة تطوير البرامج (SDK) لميزة "التنقل" أو "خرائط Google"، تأكَّد من إطلاق الموارد من خلال إعادة توجيه طرق مراحل النشاط (الموضحة بالخط الغامق) إلى navView. يمكنك إجراء ذلك باستخدام NavigationView في حزمة تطوير البرامج للتنقّل أو MapView في "خرائط Google" أو حزمة تطوير البرامج للتنقّل. يمكنك أيضًا استخدام SupportNavigationFragment أو SupportMapFragment بدلاً من استخدام NavigationView وMapView مباشرةً، على التوالي. تعالج أجزاء الدعم إعادة توجيه methods lifecycle .

class NavViewActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    navView = ...
    navView.onCreate(savedInstanceState)
    ...
  }

  override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)
    navView.onSaveInstanceState(savedInstanceState)
  }

  override fun onTrimMemory(level: Int) {
    super.onTrimMemory(level)
    navView.onTrimMemory(level)
  }

  /* Same with
    override fun onStart()
    override fun onResume()
    override fun onPause()
    override fun onConfigurationChanged(...)
    override fun onStop()
    override fun onDestroy()
  */
}

استخدام أحدث إصدارات حِزم تطوير البرامج (SDK)

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

تصحيح أخطاء تسرّب الذاكرة

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

قبل البدء، يجب أن تكون على دراية بكيفية إدارة Android لملفه الشخصي الذاكرة. للحصول على معلومات، يُرجى قراءة مقالة Android نظرة عامة على إدارة الذاكرة.

لتصحيح أخطاء تسرب الذاكرة، اتّبِع هذه العملية:

  1. أعِد إظهار المشكلة. هذه الخطوة ضرورية لتصحيح الأخطاء.
  2. تحقَّق مما إذا كان استخدام الذاكرة متوقَّعًا. تحقق من أن الاستخدام المتزايد الذي يبدو أنه تسرب ليست في الواقع الذاكرة المطلوبة لتشغيل التطبيق.
  3. تصحيح الأخطاء على مستوى عالٍ هناك العديد من الأدوات التي يمكنك استخدامها لتصحيح الأخطاء. تتوفّر ثلاث مجموعات أدوات عادية مختلفة للمساعدة في تصحيح أخطاء الذاكرة في Android، وهي: Android Studio وPerfetto وأدوات سطر الأوامر Android Debug Bridge (adb).
  4. التحقّق من استخدام تطبيقك للذاكرة: يمكنك الحصول على تتبُّع للقطات لأجزاء من الذاكرة وتخصيص ثم تحليلها.
  5. إصلاح تسرب الذاكرة:

تتناول الأقسام التالية هذه الخطوات بالتفصيل.

الخطوة 1: إعادة إنشاء المشكلة

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

  • ما هي مجموعة الميزات التي تم تفعيلها؟

  • ما هي التسلسلات المحدّدة لإجراءات المستخدمين التي تؤدي إلى حدوث التسرّب؟

    • هل حاولت تكرار عمليات تفعيل هذا التسلسل؟
  • ما هي حالات دورة الحياة التي مرّ بها التطبيق؟

    • هل جرّبت عدّة تكرارات خلال مراحل دورة الحياة المختلفة؟

تأكَّد من أنّه يمكنك إعادة إنشاء المشكلة في أحدث إصدار من حِزم SDK. قد يكون قد تم حلّ المشكلة في إصدار سابق.

الخطوة 2: التحقّق مما إذا كان استخدام الذاكرة للتطبيق متوقّعًا

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

  • تسرُّب محتمل: يؤدي تفعيل السيناريو من خلال عمليات تكرار متعددة إلى زيادة في استخدام الذاكرة بمرور الوقت.

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

  • الاستخدام المتوقّع للذاكرة: يزداد استخدام الذاكرة لفترة معيّنة ثم ينخفض تدريجيًا. قد يرجع ذلك إلى ذاكرة تخزين مؤقت محدودة أو استخدام ملف تعريف ذاكرة آخر متوقّع.

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

الخطوة 3: تصحيح الأخطاء على مستوى عالٍ

عند تصحيح أخطاء تسرُّب الذاكرة، ابدأ من مستوى عالٍ، ثم تعمَّق في التفاصيل بعد تضييق نطاق الاحتمالات. استخدِم إحدى أدوات debugging الرفيعة المستوى هذه لتحليل ما إذا كان هناك تسرّب للموارد بمرور الوقت:

أداة تحليل الذاكرة في Android Studio

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

عدادات الذاكرة في Perfetto

يمنحك Perfetto تحكمًا دقيقًا في تتبع عدة مقاييس ويقدمها كلها في مدرج تكراري واحد. لمزيد من المعلومات، يُرجى الاطّلاع على عدادات ذاكرة Perfetto.

واجهة مستخدم Perfetto

أدوات سطر الأوامر في Android Debug Bridge (adb)

إنّ الكثير من المعلومات التي يمكنك تتبُّعها باستخدام Perfetto متوفّرة أيضًا كadb أداة سطر أوامر يمكنك الاستعلام عنها مباشرةً. في ما يلي مثالان مهمان:

  • يتيح لك Meminfoاطلاعًا على معلومات مفصّلة عن الذاكرة في وقت معيّن.

  • يوفّر Procstats بعض الإحصاءات المجمّعة المهمة بمرور الوقت.

من الإحصاءات المهمة التي يجب الاطّلاع عليها هنا هي الحد الأقصى للمساحة التي يشغلها التطبيق في الذاكرة الفعلية (maxRSS) بمرور الوقت. قد لا تكون دقة MaxPSS عالية. للاطّلاع على طريقة لزيادة الدقة، راجِع علامة adb shell dumpsys procstats --help –start-testing.

تتبُّع التخصيص

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

الخطوة 4: التحقّق من استخدام تطبيقك للذاكرة باستخدام أداة تفريغ الذاكرة

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

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

  1. تسجيل نَسخة من الذاكرة
  2. تحليل ملف "تجميع الذاكرة" للعثور على عمليات تسرُّب الذاكرة
  3. إصلاح تسرب الذاكرة

لمعرفة التفاصيل، يُرجى الاطّلاع على الأقسام التالية.

تسجيل نَسْخ الذاكرة

لتسجيل نَسخة ذاكرة، يمكنك استخدام أداة Android Debug Bridge (adb) أو أداة تحليل الذاكرة في "استوديو Android".

استخدام adb لتسجيل لقطة لأجزاء من الذاكرة

لالتقاط ملف "تجميع الذاكرة" باستخدام adb، اتّبِع الخطوات التالية:

  1. وصِّل جهاز Android بالكمبيوتر.
  2. افتح موجِّه الأوامر وانتقِل إلى الدليل الذي تتوفّر فيه أدوات adb.
  3. لتسجيل لقطة لأجزاء من الذاكرة، نفِّذ الأمر التالي :

    adb shell am dumpheap my.app.name $PHONE_FILE_OUT

  4. لاسترداد ملف "تجميع الذاكرة العشوائية"، نفِّذ الأمر التالي:

    adb pull $PHONE_FILE_OUT $LOCAL_FILE.

استخدام "استوديو Android" لتسجيل نَسخة ذاكرة

لتسجيل نَسخة ذاكرة باستخدام أداة تحليل الذاكرة في "استوديو Android"، اتّبِع الخطوات التالية في قسم Android تسجيل نَسخة ذاكرة .

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

بعد تسجيل نَسخة ذاكرة، يمكنك استخدام أداة تحليل ملف ملف تحليل الذاكرة في "استوديو Android" لتحليلها. لإجراء ذلك، اتّبع الخطوات التالية:

  1. افتح مشروع Android في "استوديو Android".

  2. انقر على تشغيل، ثم على إعدادات تصحيح الأخطاء.

  3. افتح علامة التبويب أداة تحليل أداء Android.

  4. اختَر الذاكرة.

  5. اختَر فتح ملف "تجميع الذاكرة" واختَر ملف "تجميع الذاكرة" الذي أنشأته. يعرض أداة تحليل الذاكرة رسمًا بيانيًا لاستخدام تطبيقك للذاكرة.

  6. استخدِم الرسم البياني لتحليل ملف "تجميع الذاكرة العشوائية":

    • تحديد العناصر التي لم تعُد مستخدَمة

    • تحديد العناصر التي تستهلك الكثير من الذاكرة

    • الاطّلاع على مقدار الذاكرة التي يستخدمها كل عنصر

  7. استخدِم هذه المعلومات لتضييق نطاق مصدر تسرّب الذاكرة أو العثور عليه وإصلاحه.

الخطوة 5: إصلاح تسرب الذاكرة

بعد تحديد مصدر تسرُّب الذاكرة، يمكنك حلّ المشكلة. يساعد حلّ مشاكل تسرب الذاكرة في تطبيقات Android على تحسين أداء التطبيقات واستقرارها. تختلف التفاصيل حسب السيناريو. ومع ذلك، يمكن أن تساعدك الاقتراحات التالية:

أدوات تصحيح الأخطاء الأخرى

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

تصحيح أخطاء الذاكرة في الرمز الأصلي باستخدام ميزة تتبُّع التخصيص

حتى إذا لم تكن تستخدِم رمزًا أصليًا مباشرةً، فإنّ العديد من مكتبات Android الشائعة تستخدِمه، بما في ذلك حِزم SDK من Google. إذا كنت تعتقد أنّ تسرُّب الذاكرة يحدث في الرمز الأصلي، تتوفر عدة أدوات يمكنك استخدامها لتصحيح أخطاء هذا الرمز. إنّ تتبُّع التخصيص باستخدام Android Studio أو heapprofd (المتوافق أيضًا مع Perfetto) هو طريقة رائعة لتحديد الأسباب المحتملة لتسرّب الذاكرة وغالبًا ما تكون أسرع طريقة لتصحيح الأخطاء.

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

تحديد عمليات تسرُّب البيانات باستخدام LeakCanary

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

كيفية الإبلاغ عن مشاكل في حِزم تطوير البرامج (SDK) من Google

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

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

  • لقطات لأجزاء من الذاكرة التي تم التقاطها من تطبيقك مع إعادة إنشاء المشكلة سجِّل ملفّات تفريغ heap في نقطتَين زمنيتَين مختلفتَين توضِّح أنّ استخدام الذاكرة زاد بمقدار كبير.

  • إذا كان من المتوقّع حدوث تسرُّب أصلي للذاكرة، يمكنك مشاركة ناتج تتبُّع التخصيص من وضع تسجيل الدخول.

  • تقرير خطأ تم تسجيله بعد إعادة إنشاء حالة تسرُّب البيانات.

  • تتبُّع تسلسل استدعاء الدوال البرمجية لأي أعطال متعلقة بالذاكرة

    ملاحظة مهمة: لا تكفي عادةً عمليات تتبُّع تسلسل استدعاء الدوال البرمجية وحدها لتحديد وحلّ المشاكل المتعلّقة بالذاكرة، لذا احرص أيضًا على تقديم أحد أشكال المعلومات الأخرى.