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

يفترض هذا المستند أنّك اتّبعت إرشادات أفضل الممارسات المتعلّقة بتطبيقات 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.

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

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

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: إعادة إنشاء المشكلة

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

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

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

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

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

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

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

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

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

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

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

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

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

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

أداة تحليل الذاكرة في 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" مما إذا كان هناك نشاط أو جزء التي لا يزال من الممكن الوصول إليها، ولكن سبق أن تم تدميرها.

  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 في نقطتَين زمنيتَين مختلفتَين توضِّح أنّ استخدام الذاكرة زاد بمقدار كبير.

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

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

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

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