على الرغم من أنّ أداء التطبيق غالبًا ما يرتبط بواجهة مستخدم سلسة وأوقات بدء سريعة، إلا أنّ الذاكرة هي الأساس الصامت الذي تُبنى عليه هذه المقاييس المرئية. لم يعُد سرًا أنّنا نشهد تحوّلاً أصبح فيه حجم ذاكرة الجهاز أكثر أهمية من أي وقت مضى. لم نكتفِ بتحقيق تقدّم في تحسين استخدام الذاكرة على Android 17، بل نوفّر أيضًا الأدوات وإمكانية استخدام واجهات برمجة التطبيقات لمساعدتك في الاستعداد لمتطلبات الذاكرة الأكثر صرامة في وقت لاحق من هذا العام.
لضمان استقرار الجهاز، سيبدأ النظام في Android 17 بفرض حدود على الذاكرة المستخدَمة من التطبيقات استنادًا إلى إجمالي مساحة ذاكرة الوصول العشوائي (RAM) في الجهاز. إذا تجاوز أحد التطبيقات هذه الحدود، سيوقف نظام التشغيل Android العملية بدون تتبُّع تسلسل استدعاء الدوال البرمجية المرتبط بها.
وبالإضافة إلى عمليات الإنهاء الإجباري هذه، يؤدي استخدام الذاكرة بشكل غير محسّن إلى تدهور تجربة المستخدم حتمًا. عندما يقترب التطبيق من حدود ذاكرة الكومة، يؤدي ذلك إلى تفعيل عملية جمع البيانات المُهمَلة بشكل متكرر، ما يؤدي إلى حدوث تقطُّع ملحوظ في واجهة المستخدم. علاوةً على ذلك، عندما تنفد الذاكرة المتوفرة في الجهاز، يسعى النظام إلى استرداد الصفحات، ما يؤدي إلى إجهاد وحدة المعالجة المركزية (CPU) وتأخُّر واجهة المستخدم واستهلاك البطارية. إذا كان نقص الذاكرة شديدًا جدًا، يمكن أن يؤدي إلى أحداث Low Memory Killer (LMK) التي توقف العمليات في الخلفية فجأة وتجبر التطبيقات على بدء التشغيل البارد ببطء وفقدان حالة المستخدم.
لإنشاء تطبيقات عالية الأداء وتجنُّب عمليات الإنهاء الإجباري هذه، ننصحك باتّباع استراتيجيات تحسين الذاكرة التالية:
- زيادة تحسين الرمز الثانوي إلى أقصى حد باستخدام R8
- تحسين تحميل الصور
- رصد تسريبات الذاكرة وإصلاحها باستخدام "استوديو Android"
- تقليل استخدام الذاكرة عند خروج التطبيق من حالة العرض
- مراقبة الذاكرة المتقدّمة باستخدام ProfilingManager
يتوفّر أيضًا إصدار مختصر من مشاركة المدوّنة هذه بتنسيق الفيديو، ننصحك بمشاهدته.
التعرّف على الحدود القصوى لذاكرة التطبيقات في Android 17
نقدّم في Android 17 حدودًا للذاكرة المستخدَمة من التطبيقات لمنع "جهة مسيئة واحدة" من إفساد تجربة تعدُّد المهام واستقرار الجهاز بالكامل.
في ما يلي تفاصيل عن الأسباب التي أدّت إلى هذا التغيير في البنية:
- منع عمليات الإغلاق المتتالية: عندما يصبح التطبيق كبيرًا جدًا أو يحدث تسريب للذاكرة أثناء احتفاظه بحالة مميزة (مثل تشغيل خدمة تعمل في المقدّمة)، تتم حمايته في البداية من أداة Low Memory Killer (LMK) في النظام. ومع زيادة حجم هذا التطبيق الواحد بدون قيود وتخزينه كمية كبيرة من ذاكرة الوصول العشوائي، يضطر نظام LMK إلى التعويض عن ذلك من خلال إيقاف عشرات التطبيقات الصغيرة المخزّنة مؤقتًا والمهام التي تعمل في الخلفية لاستعادة المساحة التي يستهلكها التطبيق.
- الحفاظ على إمكانية تنفيذ مهام متعددة وحالة المستخدم: عندما يضطر النظام إلى إزالة التطبيقات المخزّنة مؤقتًا لاستيعاب عملية واحدة تتسبّب في حدوث تسرّب، تتدهور تجربة تنفيذ المهام المتعددة بشكل كبير. يواجه المستخدمون الذين يعودون إلى التطبيقات المخزّنة مؤقتًا السابقة عمليات بدء بارد بطيئة بدلاً من عمليات استئناف دافئ شبه فورية. يؤدي عدم الكفاءة هذا إلى زيادة الضغط على وحدة المعالجة المركزية (CPU) وتسريع استنزاف البطارية. ويمكنه أيضًا إزالة سياق المستخدم في التطبيقات المستخدَمة مؤخرًا، مثل مواضع التمرير ومجموعات التنقّل ومستوى التقدّم في اللعبة.
لتحديد ما إذا كانت قيود الحقل هذه قد أثّرت في جلسة تطبيقك، يمكنك طلب getDescription() ضِمن ApplicationExitInfo. إذا فرض النظام حدًا، سيتم تسجيل سبب الخروج على أنّه REASON_OTHER وسيتضمّن سلسلة الوصف "MemoryLimiter:AnonSwap". يمكنك أيضًا الاستفادة من إنشاء الملفات الشخصية المستند إلى المشغّلات باستخدام TRIGGER_TYPE_ANOMALY لتسجيل نُسخ الذاكرة تلقائيًا عند بلوغ الحدّ الأقصى للذاكرة. بالإضافة إلى ذلك، يعمل فريق Android بنشاط على إتاحة المزيد من مقاييس الذاكرة أثناء الاستخدام للمطوّرين في Google Play Console.
لقد وسّعنا أيضًا مستندات حدود الذاكرة لتشمل أوامر تصحيح الأخطاء المحلية، ما يتيح لك محاكاة قيود الذاكرة في بيئتك المحلية والتحقّق من سلوك تطبيقك في ظلّ أيّ فرض لحدود الذاكرة.
زيادة تحسين الرمز الثانوي إلى أقصى حد باستخدام R8
تتمثّل إحدى الطرق الفعّالة للغاية لتقليل استهلاك الذاكرة في تطبيقك في تفعيل أداة التحسين R8. من خلال تقليص الفئات والطرق والحقول إلى أسماء أقصر وإزالة الرموز والموارد غير المستخدَمة، يقلّل R8 بشكل كبير من استهلاك الذاكرة الذي يشغله تطبيقك عن طريق تقليل مقدار الرموز المقيمة المطلوبة أثناء التنفيذ.
يقلّل R8 من حجم الذاكرة المستخدَمة ويقلّل من خطر إنهاء العملية بسبب LMK. ويؤدي ذلك إلى زيادة عدد عمليات إعادة التشغيل البطيء مقارنةً بعمليات التشغيل المتأخِّر على البارد. بالإضافة إلى ذلك، يقلّل رمز البايت المبسّط من الحمل الزائد لوحدة المعالجة المركزية في سلسلة التعليمات الرئيسية، ما يؤدي مباشرةً إلى خفض معدّلات أخطاء ANR وتوفير تجربة أكثر سلاسة للمستخدم. على سبيل المثال، فعّل البنك الرقمي Monzo ميزة التحسين الكامل باستخدام R8، ولاحظ انخفاضًا بنسبة% 35 في معدّل أخطاء ANR، وتحسّنًا بنسبة% 30 في معدّل التشغيل على البارد، وانخفاضًا بنسبة% 9 في الحجم الإجمالي للتطبيق.
لضبط إعدادات R8 بشكل صحيح في ملف build.gradle، اتّبِع الخطوات التالية:
- اضبط
isShrinkResources = trueوisMinifyEnabled = true. - استخدِم
proguard-android-optimize.txtبدلاً منproguard-android.txtالقديم الذي يمنع التحسينات ولم يعُد متاحًا في الإصدار 9 من المكوّن الإضافي لنظام Gradle المتوافق مع Android. - إزالة
android.enableR8.fullMode = falseمنgradle.properties
إذا كنت تستخدم الانعكاس في قاعدة الرموز البرمجية، أضِف قواعد Keep لمنع R8 من تحسين أجزاء الرموز هذه. احرص على تحديد نطاق قواعد الاحتفاظ بشكل ضيق للحصول على أقصى قدر من التحسين.
للحصول على أقصى قدر من التحسين، احرص على اتّباع أفضل الممارسات التالية في ملف قاعدة الاحتفاظ.
- إزالة الخيارات العامة، مثل
-dontoptimizeو-dontshrinkو-dontobfuscate، التي تمنع R8 من تحسين قاعدة الرموز البرمجية بأكملها - أزِل قواعد الاحتفاظ التي تمنع تحسين مكونات Android، مثل الأنشطة أو الخدمات أو طرق العرض أو أجهزة استقبال البث.
- حسِّن قواعد الاحتفاظ الواسعة على مستوى الحزمة لاستهداف فئات أو طرق معيّنة فقط.
للاطّلاع على المزيد من أفضل الممارسات، يمكنك الاطّلاع على مستندات قواعد الاحتفاظ.
أفضل الممارسات المتعلّقة بمكتبة R8 للمطوّرين
إذا كنت مطوّر مكتبة، عليك وضع القواعد التي يحتاجها المستهلكون في ملف consumer-rules file، والاحتفاظ بقواعد الحماية الداخلية للمكتبة في ملف proguard-rules.pro. لمزيد من المعلومات حول كيفية تحسين المكتبات، يُرجى الاطّلاع على تحسين المكتبات لمطوّريها.
أداة تحليل إعدادات R8
للتدقيق في عملية تحسين R8، استخدِم أداة تحليل الإعدادات. يعرض "محلّل الإعداد" الحالة الحالية للتحسين باستخدام نتائج "التشويش" و"التحسين" و"التقليل". باستخدام أداة تحليل الإعدادات، يمكنك أيضًا معرفة عدد الفئات أو الطرق أو الحقول التي تمنع كل قاعدة الاحتفاظ من التحسين. يمكنك تحسين قواعد الاحتفاظ الواسعة النطاق على مستوى الحزمة للاستفادة من أقصى قدر من التحسين.
باستخدام أداة تحليل الإعدادات، يمكنك أيضًا تحديد قواعد الاحتفاظ التي تتضمّن قواعد احتفاظ أخرى، وقواعد الاحتفاظ المكرّرة، وقواعد الاحتفاظ غير المستخدَمة.
مهارة وكيل R8
يمكنك أيضًا الاستفادة من مهارة وكيل R8 باستخدام وكيل استوديو Android أو أدوات الذكاء الاصطناعي الأخرى لحلّ الأخطاء في الإعدادات وتحسين قواعدك، ما يؤدي إلى تحسين أداء التطبيق. (ستتطلّب الإحصاءات المستندة إلى المهارات المستندة إلى الذكاء الاصطناعي عملية تحقّق فنية)
تحسين تحميل الصور
عادةً ما تكون الصور النقطية هي أكبر العناصر الشائعة التي يتم تخزينها في ذاكرة تطبيقك. وهي تمثّل المرحلة النهائية من عملية تحميل الصور حيث يتم فك ترميز الملفات المضغوطة، مثل ملفات JPEG أو PNG، إلى بيانات وحدات البكسل الأولية لعرضها. وهذا يعني أنّ صورة مضغوطة صغيرة بحجم 100 كيلوبايت يمكن أن تتضخم إلى عدة ميغابايت من ذاكرة الوصول العشوائي لأنّ استهلاك الذاكرة يتحدّد بأبعاد الصورة بالبكسل وعمق الألوان. بما أنّ عمليات الصور النقطية تكون غالبًا في المسار الحرج لرسم اللقطات، فإنّ الصور غير المحسَّنة تتسبّب في تضخّم كبير في الذاكرة وتشوّش في واجهة المستخدم.
تنصح Google باستخدام مكتبات تحميل الصور Coil للمشاريع التي تستخدم Kotlin في المقام الأول، خاصةً عند التطوير باستخدام Jetpack Compose، وGlide للتطبيقات المستندة إلى Java.
اتّبِع أفضل خمس ممارسات
- تقليل دقة الصور: إذا كنت تحمّل الصور النقطية يدويًا، تجنَّب تحميل صورة كبيرة جدًا في عرض مصغّر صغير، واستخدِم inSampleSize لتحميل نسخة أصغر. تخفّض Glide وCoil دقة الصور تلقائيًا، ويمكنك ضبط استراتيجية تخفيض الدقة هذه باستخدام DownsampleStrategy وImageLoader على التوالي.
- الاقتصاص: تجنَّب تضمين مساحة فارغة مباشرةً في ملف صورة لأغراض عرض الصورة ضمن إطار (على سبيل المثال، إنشاء حدود شفافة لتوسيع أبعاد الصورة). بدلاً من تضمين هذه الحدود، استخدِم InsetDrawable أو أضِف مساحة متروكة مباشرةً داخل العرض أو العنصر القابل للإنشاء الذي يحتوي على الصورة النقطية.
- الإعداد: يمكنك تحقيق التوازن بين الذاكرة والجودة من خلال اختيار تنسيق البكسل المناسب. استخدِم
RGB_565عندما لا تكون الشفافية مطلوبة، ما يؤدي إلى استخدام نصف الذاكرة التي يستخدمها التنسيقARGB_8888التلقائي. في Glide، يمكنك ضبط ذلك باستخدام DecodeFormat، وفي Coil، يمكنك استخدام الخاصية bitmapConfig. - تحديد أولويات الرسومات المتجهة القابلة للرسم: بالنسبة إلى مواد العرض الهندسية الأساسية، استخدِم ShapeDrawable كبديل بسيط لفك ترميز الصور النقطية. من خلال تحديد مواد العرض هذه مرة واحدة عبر XML، يمكنك ضمان توسيع نطاقها بسلاسة على جميع كثافات العرض مع التخلص بشكل فعّال من تضخّم الذاكرة الناتج عن الموارد.
- إعادة الاستخدام: إذا كان تطبيقك يدير الصور النقطية يدويًا، يجب أن يستدعي التطبيق
bitmap.recycle()ويتجاهل مرجعBitmapعلى الفور عندما لا تعود هناك حاجة إلى صورة نقطية، وذلك للحدّ من الاستخدام الزائد للذاكرة. إذا كنت تستخدم مكتبة لتحميل الصور، مثل Glide أو Coil، أعِد الصورة النقطية إلى مجموعة المكتبة المُدارة. من خلال توفير مساحة تخزين مؤقت حالية لتلبية احتياجات الذاكرة المستقبلية، تتجنّب المجموعة بشكل فعّال تكلفة عمليات التخصيص الجديدة.
يمكنك الاطّلاع على مستنداتنا حول تحسين أداء الصور لمعرفة المزيد.
أدوات "استوديو Android"
يمكنك أيضًا إزالة الصور النقطية المكرّرة باستخدام الإصدار الرابع من استوديو Android Narwhal. في ما يلي كيفية العثور عليها في خمس خطوات بسيطة:
- افتح علامة التبويب Profiler في "استوديو Android"
- انقر على Heap Dump (أو "تحليل استخدام الذاكرة") ثم انقر على "تسجيل" لأخذ لقطة لحالة الذاكرة الحالية لتطبيقك.
- ابحث في نتائج التحليل عن مثلث التحذير الأصفر ⚠️ الذي يستخدمه "استوديو Android" للإشارة إلى الصور النقطية المكرّرة التي يتم تخزينها عدة مرات. بدلاً من ذلك، انتقِل إلى عنوان أداة Profiler، واختَر "الفلترة حسب:" (Filter by:)، ثمّ اختَر الإعداد "تكرار الصور النقطية" (Duplicate Bitmaps).
- انقر على أي إدخال تم الإبلاغ عنه لفتح جزء معاينة الصورة النقطية، ما يتيح لك معرفة الصورة التي تم تكرارها بالضبط.
- استخدِم هذا التأكيد المرئي لتتبُّع منطق التحميل المكرّر في الرمز البرمجي وتنفيذ استراتيجية تخزين مؤقت أفضل.
رصد تسريبات الذاكرة وإصلاحها باستخدام "استوديو Android"
تحدث تسريبات الذاكرة في Android عندما يحتفظ الرمز البرمجي بمرجع كائن لفترة طويلة بعد انتهاء دورة حياته. يمنع ذلك "جامع البيانات غير المستخدَمة" (GC) من استرداد هذه الذاكرة، ما يؤدي في النهاية إلى بطء الأداء أو حدوث الخطأ OutOfMemoryError (OOM).
يتضمّن الإصدار 3 من استوديو Android Panda مهمة LeakCanary مخصّصة لتحديد المشاكل، ما يتيح للمطوّرين تحليل تسربات الذاكرة في الوقت الفعلي وتحديد مساراتها مباشرةً في بيئة التطوير المتكاملة.
تنقل مهمة أداة LeakCanary لتوصيف الأداء في "استوديو Android" عملية تحليل تسرُّب الذاكرة من جهازك إلى جهاز التطوير، ما يؤدي إلى تحسين الأداء بشكل كبير خلال مرحلة تحليل تسرُّب الذاكرة مقارنةً بتحليل تسرُّب الذاكرة على الجهاز فقط.
بالإضافة إلى ذلك، يتم الآن وضع تحليل تسرب الذاكرة في سياقه ضمن بيئة التطوير المتكاملة ودمجه بالكامل مع رمز المصدر، ما يوفّر ميزات مثل الانتقال إلى تعريف المتغير وغير ذلك من عمليات الربط المفيدة بين الرموز البرمجية التي تقلّل بشكل كبير من الجهد والوقت اللازمين للتحقيق في تسرب الذاكرة وإصلاحه.
أمثلة على تسربات الذاكرة الشائعة
تحدث تسرّبات الذاكرة عندما يستمرّ وجود عنصر في الذاكرة بعد انتهاء مدة بقائه المفترضة. يحدث ذلك عادةً للأسباب التالية:
- الاحتفاظ بمراجع إلى "القصاصات" أو "الأنشطة" أو "طرق العرض" التي لم يعُد يتم استخدامها
- إساءة إدارة مراجع Context
- عدم إلغاء تسجيل المراقبين والمستمعين والمستلِمين بشكل صحيح
- إنشاء مراجع ثابتة للعناصر المرتبطة بمكوّنات ذات دورات حياة أقصر
في ما يلي بعض الأمثلة على السيناريوهات:
| السيناريو | مثال مستند إلى Compose | مثال مستند إلى العرض |
| تسريب السياق | مثال: الحل: | مثال: الحلّ: |
| تسريب أدوات معالجة الأحداث | مثال: الحلّ: | مثال: الحلّ: |
| Leaking Views | مثال:
| مثال: الحلّ: |
تقليل استخدام الذاكرة عند خروج التطبيق من حالة العرض
يمكن لنظام التشغيل Android استعادة الذاكرة من تطبيقك أو إيقافه تمامًا إذا لزم الأمر لإتاحة مساحة ذاكرة للمهام المهمة، كما هو موضّح في نظرة عامة على إدارة الذاكرة. عادةً ما يسترد نظام التشغيل Android الذاكرة من تطبيقك عندما لا يكون مرئيًا للمستخدم، وذلك مثلاً عن طريق تجاهل بعض صفحات الرموز والبيانات في تطبيقك في الذاكرة أو ضغط عمليات تخصيص الذاكرة المؤقتة. عندما يستأنف المستخدم تطبيقك ويحاول تطبيقك الوصول إلى بعض الذاكرة التي تمت استعادتها، سيقوم نظام التشغيل بإعادة تبديل هذه الذاكرة عند الطلب. يمكن أن يكون سلوك التبديل هذا بطيئًا، وقد يتسبب في حدوث تشوّش أو تقطُّع غير متوقّع في تطبيقك.
إذا تركت لنظام التشغيل تحديد الذاكرة التي سيستردّها من تطبيقك، قد تجد أنّه استردّ ذاكرة ستحتاج إليها بعد فترة قصيرة من استئناف تطبيقك. وبدلاً من ذلك، يمكن لتطبيقك تجاهل عمليات تخصيص الذاكرة التي يمكنه إعادة إنشائها لاحقًا عند الطلب وبتكلفة منخفضة. لإجراء ذلك، يمكنك تنفيذ واجهة ComponentCallbacks2. يمكنك تنفيذ onTrimMemory في Activity أو Fragment أو Service أو حتى فئة Application المخصّصة. يُعدّ استخدامها في فئة Application فعّالاً للغاية لإدارة ذاكرة التخزين المؤقت العامة.
يُعلم أسلوب onTrimMemory() لردّ الاتصال المقدَّم تطبيقك بالأحداث المتعلّقة بدورة الحياة أو الذاكرة والتي تتيح فرصة جيدة لتطبيقك لتقليل استخدام الذاكرة طوعًا.
في ما يتعلّق بإدارة دورة حياة الذاكرة، يجب أن يركّز التنفيذ حصريًا على TRIM_MEMORY_UI_HIDDEN وTRIM_MEMORY_BACKGROUND. منذ الإصدار 14 من نظام التشغيل Android، توقّف النظام عن إرسال إشعارات بشأن الثوابت القديمة الأخرى التي تم إيقافها نهائيًا في الإصدار 15 من نظام التشغيل Android.
TRIM_MEMORY_UI_HIDDEN: تشير هذه الإشارة إلى أنّ واجهة مستخدم تطبيقك لم تعُد ظاهرة للمستخدم. ويوفّر ذلك فرصة لإصدار عمليات تخصيص كبيرة للذاكرة مرتبطة بشكل صارم بالواجهة، مثل الصور النقطية أو مخازن مؤقتة لتشغيل الفيديو أو موارد الرسوم المتحركة المعقّدة.
TRIM_MEMORY_BACKGROUND: في هذا المستوى، تكون عمليتك مقيمة في الخلفية وهي الآن مرشّحة للإنهاء لتلبية احتياجات الذاكرة العامة للنظام. لتمديد المدة التي تظل فيها عمليتك في حالة التخزين المؤقت وتقليل عدد عمليات بدء تشغيل التطبيق الباردة، عليك إيقاف أي موارد يمكن إعادة إنشائها بسهولة بمجرد أن يستأنف المستخدم جلسته.
import android.content.ComponentCallbacks2 // Other import statements. class MainActivity : AppCompatActivity(), ComponentCallbacks2 { /** * Release memory when the UI becomes hidden or when system resources become low. * @param level the memory-related event that is raised. */ override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
ملاحظة: قد يعتمد دمج onTrimMemory على توفّر حزمة SDK. على سبيل المثال، تعتمد بعض الألعاب على محرك الألعاب لتفعيل هذه الإمكانية. يُرجى الاطّلاع على مستندات تحسين ذاكرة الألعاب.
مراقبة الذاكرة المتقدّمة باستخدام ProfilingManager
لرصد مشاكل الذاكرة وتشخيصها في بيئة الإنتاج التي لا يمكن إعادة إنتاجها محليًا، عليك الاستفادة من ProfilingManager API. تتيح لك واجهة برمجة التطبيقات المتقدّمة هذه التي تم طرحها في Android 15 جمع ملفات تعريف Perfetto للمستخدمين الفعليين آليًا.
بالنسبة إلى الفِرق التي لا تتوفّر لديها بنية أساسية مخصّصة لإدارة عناصر الأداء واستضافتها، تعمل Crashlytics على استكشاف حلّ متخصص لتبسيط مسار العمل هذا. وهي تدعو المطوّرين إلى تقديم ملاحظات.
يقدّم نظام التشغيل Android 17 عوامل تشغيل جديدة مستندة إلى الأحداث، وأبرزها TRIGGER_TYPE_OOM وTRIGGER_TYPE_ANOMALY:
- تجمع أداة تشغيل OOM تلقائيًا لقطة لأجزاء من الذاكرة في Java في اللحظة التي يحدث فيها تعطّل OutOfMemoryError، ما يوفّر حالات تخصيص دقيقة. يتم تقديم ملف OOM الذي تم جمعه في المرة التالية التي يبدأ فيها التطبيق ويسجّل دالة الاستدعاء
registerForAllProfilingResults. - يرصد مشغّل رصد الحالات الشاذة مشاكل الأداء الخطيرة، مثل الإفراط في نشر محتوى غير مرغوب فيه في الحزم أو تجاوز حدود الذاكرة. تقدّم حالة عدم تطابق الذاكرة لقطة لأجزاء من الذاكرة قبل أن يوقف النظام التطبيق.
val profilingManager = applicationContext.getSystemService(ProfilingManager::class.java) val triggers = ArrayList<ProfilingTrigger>() triggers.add(ProfilingTrigger.Builder( ProfilingTrigger.TRIGGER_TYPE_ANOMALY)) val mainExecutor: Executor = Executors.newSingleThreadExecutor() val resultCallback = Consumer<ProfilingResult> { profilingResult -> if (profilingResult.errorCode != ProfilingResult.ERROR_NONE) { // upload profile result to server for further analysis setupProfileUploadWorker(profilingResult.resultFilePath) } profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback) profilingManager.addProfilingTriggers(triggers)
بعد جمع لقطة لأجزاء من الذاكرة، يمكنك تنزيل الملف الشخصي من الخادم أو محليًا من خلال الأمر Adb pull وسحب الملف وإفلاته في واجهة مستخدم Perfetto. لتبسيط سير عمل تصحيح أخطاء الذاكرة، استخدِم مستكشف نُسخ الذاكرة، وهو العرض التلقائي الجديد لنُسخ الذاكرة في واجهة مستخدم Perfetto. توفّر هذه الأداة واجهة سهلة الاستخدام لفحص لقطات أجزاء الذاكرة في Java، ما يتيح لك عرض التسلسل الهرمي لتخصيص العناصر، واحتساب أحجام الذاكرة المحفوظة، وتحديد أقصر مسار من جذر جمع البيانات المُهمَلة. باستخدام أداة Heap Dump Explorer، يمكنك تحديد تسربات الذاكرة بسرعة، والعناصر المحتجزة المتضخّمة، مثل عمليات تخصيص الصور النقطية المفرطة، وتحليل عمليات تخصيص عناصر الذاكرة المؤقتة في مكان واحد.
الخاتمة
يُعدّ تحسين الرمز الثانوي باستخدام R8 واتّباع أفضل الممارسات لتحميل الصور وحلّ المشاكل المتعلّقة بتسرُّب الذاكرة خطوات مهمة لتقديم تجربة مستخدم عالية الجودة مع إدارة الموارد بفعالية في ظل الضغط. يساعد اتّخاذ هذه الإجراءات الاستباقية في الحفاظ على ثبات التطبيق وأدائه، ما يمنع عمليات الإغلاق غير المتوقّعة مع الحفاظ على سياق المستخدم. لتعزيز خبرتك في الأداء، يمكنك الاطّلاع على إرشادات الذاكرة المعدَّلة.
-
طرق التنفيذإدراكًا منّا أنّ استنزاف البطارية بشكل مفرط هو من أهم المشاكل التي تواجه مستخدمي Android، اتّخذت Google خطوات مهمة لمساعدة المطوّرين في إنشاء تطبيقات أكثر كفاءة في استهلاك الطاقة.
Alice Yuan • مدة القراءة: 8 دقائق -
طرق التنفيذيتضمّن دليل تسوية الأداء 5 مستويات. سنبدأ بالمستوى 1 الذي يقدّم أدوات أداء تتطلّب الحد الأدنى من جهد التكيّف، وسننتقل إلى المستوى 5 المثالي للتطبيقات التي لديها الموارد اللازمة للحفاظ على إطار عمل مخصّص للأداء.
Alice Yuan • يستغرق الاطّلاع على المقال 9 دقائق -
طرق التنفيذعند العمل على ميزات جديدة، غالبًا ما يكون أداء التطبيق من الأولويات الثانوية. ومع ذلك، على الرغم من أنّ هذا الأمر ليس من أولويات المطوّرين دائمًا، يمكن للمستخدمين معرفة مواضع ضعف أداء تطبيقك بالضبط.
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.