يُعدّ تحسين استخدام الذاكرة أمرًا بالغ الأهمية لضمان سلاسة الأداء ومنع تعطُّل التطبيقات والحفاظ على استقرار النظام وسلامة المنصة. مع أنّه يجب مراقبة استخدام الذاكرة وتحسينه في كل تطبيق، تواجه تطبيقات المحتوى لأجهزة التلفزيون تحديات معيّنة تختلف عن تطبيقات Android النموذجية للأجهزة الجوّالة.
يمكن أن يؤدي الاستهلاك المرتفع للذاكرة إلى حدوث مشاكل في سلوك التطبيقات والنظام، بما في ذلك:
- قد يصبح التطبيق نفسه بطيئًا أو متأخرًا، أو قد يتم إغلاقه في أسوأ الحالات.
- تصبح خدمات النظام المرئية للمستخدم (مثل التحكّم بمستوى الصوت ولوحة بيانات إعدادات الصور ومساعد Google وما إلى ذلك) بطيئة جدًا أو قد لا تعمل على الإطلاق.
- قد يتفاعل عملية البرنامج الخفي لإغلاق التطبيقات بسبب نقص الذاكرة (LMK) مع الضغط العالي على الذاكرة من خلال إغلاق العمليات الأقل أهمية، ثم قد تتم إعادة تشغيل هذه المكوّنات بعد فترة وجيزة، ما يؤدي إلى حدوث ارتفاعات في التنازع على الموارد يمكن أن يؤثر بشكل مباشر في التطبيق الذي يعمل في المقدّمة.
- قد يتأخّر الانتقال إلى مشغّل التطبيقات بشكل كبير، ما يؤدي إلى ظهور تطبيق يعمل في المقدّمة على أنّه لا يستجيب إلى أن ينتهي الانتقال.
- قد يبدأ النظام في استخدام استرداد الذاكرة المباشر، ما يؤدي إلى إيقاف تنفيذ سلسلة التعليمات مؤقتًا أثناء انتظار تخصيص الذاكرة. ويمكن أن يحدث ذلك لأي سلسلة تعليمات، مثل سلسلة التعليمات الرئيسية أو سلاسل التعليمات ذات الصلة ببرامج الترميز، ما قد يؤدي إلى حدوث مشاكل في الصوت والفيديو، بالإضافة إلى أخطاء في واجهة المستخدم.
اعتبارات الذاكرة على أجهزة التلفزيون
عادةً ما تكون ذاكرة أجهزة التلفزيون أقل بكثير من ذاكرة الهواتف أو الأجهزة اللوحية. على سبيل المثال، يمكننا رؤية إعدادات على التلفزيون تتضمّن ذاكرة وصول عشوائي (RAM) بسعة 1 غيغابايت ودقة فيديو 1080p. في الوقت نفسه، تتضمّن معظم تطبيقات التلفزيون ميزات متشابهة، وبالتالي تتشابه عملية التنفيذ والتحديات الشائعة. تتسبّب هاتان الحالتان في حدوث مشاكل لا تظهر في أنواع الأجهزة والتطبيقات الأخرى:
- تتألف تطبيقات وسائط التلفزيون عادةً من طرق عرض الصور على شكل شبكة وصور خلفية بملء الشاشة، ما يتطلّب تحميل الكثير من الصور في الذاكرة خلال فترة زمنية قصيرة.
- تُشغّل تطبيقات التلفزيون بث الوسائط المتعددة الذي يتطلب تخصيص مقدار معيّن من الذاكرة لتشغيل الفيديو والصوت، كما تحتاج إلى مخازن مؤقتة كبيرة للوسائط لضمان التشغيل السلس.
- يمكن أن تؤدي ميزات الوسائط الإضافية (مثل البحث عن موضع معيّن، وتغيير الحلقة، وتغيير المقطع الصوتي، وما إلى ذلك) إلى زيادة الضغط على الذاكرة إذا لم يتم تنفيذها بشكل صحيح.
التعرّف على أجهزة التلفزيون
يركّز هذا الدليل بشكل أساسي على استخدام التطبيقات للذاكرة واستهدافات الذاكرة للأجهزة ذات ذاكرة الوصول العشوائي المنخفضة.
على أجهزة التلفزيون، يجب مراعاة الخصائص التالية:
- ذاكرة الجهاز: تشير إلى مقدار ذاكرة الوصول العشوائي (RAM) المثبّتة على الجهاز.
- دقة عرض واجهة مستخدم الجهاز: هي الدقة التي يستخدمها الجهاز لعرض واجهة مستخدم نظام التشغيل والتطبيقات، وتكون عادةً أقل من دقة عرض الفيديو على الجهاز.
- دقة الفيديو: هي الحد الأقصى لدقة الفيديوهات التي يمكن للجهاز تشغيلها.
ويؤدي ذلك إلى تصنيف أنواع الأجهزة المختلفة وطريقة استخدام الذاكرة فيها.
ملخّص أجهزة التلفزيون
| ذاكرة الجهاز | درجة دقة الفيديو على الجهاز | درجة دقة واجهة مستخدم الجهاز | isLowRAMDevice() |
|---|---|---|---|
| 1 غيغابايت | 1080 بكسل | 720 بكسل | نعم |
| 1.5 غيغابايت | 2160p | 1080 بكسل | نعم |
| 1.5 غيغابايت أو أكثر | 1080 بكسل | 720p أو 1080p | لا* |
| ≥ 2 غيغابايت | 2160p | 1080 بكسل | لا* |
أجهزة تلفزيون ذات ذاكرة وصول عشوائي (RAM) منخفضة
تكون هذه الأجهزة في وضع محدودية الذاكرة وسيتم ضبط قيمة
ActivityManager.isLowRAMDevice()
على "صحيح". يجب أن تنفّذ التطبيقات التي تعمل على أجهزة تلفزيون ذات ذاكرة وصول عشوائي (RAM) منخفضة إجراءات إضافية للتحكّم في الذاكرة.
نصنّف الأجهزة التي تتضمّن الخصائص التالية ضمن هذه الفئة:
- الأجهزة التي تبلغ سعة ذاكرة الوصول العشوائي فيها 1 غيغابايت: ذاكرة وصول عشوائي بسعة 1 غيغابايت، ودقة واجهة المستخدم 720p/HD (1280x720)، ودقة الفيديو 1080p/FullHD (1920x1080)
- الأجهزة التي تبلغ سعة ذاكرتها 1.5 غيغابايت: ذاكرة وصول عشوائي بسعة 1.5 غيغابايت، ودقة واجهة المستخدم 1080p/FullHD (1920x1080)، ودقة الفيديو 2160p/UltraHD/4K (3840x2160)
- حالات أخرى حدّد فيها المصنّع الأصلي للجهاز العلامة
ActivityManager.isLowRAMDevice()بسبب قيود إضافية على الذاكرة
أجهزة التلفزيون العادية
ولا تعاني هذه الأجهزة من ضغط كبير على الذاكرة. نرى أنّ هذه الأجهزة تتضمّن الخصائص التالية:
- ذاكرة وصول عشوائي (RAM) بسعة 1.5 غيغابايت أو أكثر، وواجهة مستخدم بدقة 720p أو 1080p، وفيديوهات بدقة 1080p
- ذاكرة وصول عشوائي (RAM) بسعة 2 غيغابايت أو أكثر، وواجهة مستخدم بدقة 1080p، وفيديوهات بدقة 1080p أو 2160p
ولا يعني هذا أنّه لا يجب على التطبيقات الاهتمام باستخدام الذاكرة على هذه الأجهزة، لأنّ بعض حالات إساءة استخدام الذاكرة لا تزال تؤدي إلى استنفاد الذاكرة المتاحة وتؤدي إلى ضعف الأداء.
استهداف الذاكرة على أجهزة التلفزيون ذات ذاكرة الوصول العشوائي المنخفضة
عند قياس الذاكرة على هذه الأجهزة، ننصح بشدة بمراقبة كل قسم من الذاكرة باستخدام أداة تحليل استخدام الذاكرة في "استوديو Android". يجب أن تحدّد تطبيقات التلفزيون استخدامها للذاكرة وأن تعمل على إبقاء فئاتها دون الحدود التي نحدّدها في هذا القسم.

في قسم كيف يتم احتساب الذاكرة، ستجد شرحًا تفصيليًا لأرقام الذاكرة التي تم تسجيلها. بالنسبة إلى تعريف الحدود الدنيا لتطبيقات التلفزيون، سنركّز على ثلاث فئات من الذاكرة:
- الوضع "مجهول الهوية" + "التبديل": يتألف من Java + Native + ذاكرة تخصيص المكدس في "استوديو Android".
- الرسومات: يتم عرضها مباشرةً في أداة Profiler. تتألف عادةً من نقوش رسومات.
- الملف: يتم تصنيفه ضمن الفئتين "الرمز" و "غير ذلك" في استوديو Android.
باستخدام هذه التعريفات، يوضّح الجدول التالي الحدّ الأقصى للقيمة التي يجب أن يستخدمها كل نوع من أنواع مجموعات الذاكرة:
| نوع الذاكرة | Purpose | أهداف الاستخدام (1 غيغابايت) |
|---|---|---|
| مجهول الهوية + تبديل (Java + Native + Stack) | تُستخدَم في عمليات التخصيص ومخازن وسائط مؤقتة والمتغيرات وغيرها من المهام التي تتطلّب استخدامًا مكثّفًا للذاكرة. | < 160 MB |
| الرسومات | تستخدمها وحدة معالجة الرسومات (GPU) للنسيج والمخازن المؤقتة ذات الصلة بالعرض | من 30 إلى 40 ميغابايت |
| ملف | تُستخدَم لصفحات الرموز والملفات في الذاكرة. | 60-80 ميغابايت |
يجب ألا يتجاوز إجمالي الذاكرة (Anon+Swap + Graphics + File) ما يلي:
- 280 ميغابايت من إجمالي استخدام الذاكرة (Anon+Swap + Graphics + File) للأجهزة التي تبلغ سعة ذاكرة الوصول العشوائي فيها أقل من 1 غيغابايت.
ننصح بشدة بعدم تجاوز ما يلي:
- 200 ميغابايت من استخدام الذاكرة على (Anon+Swap + الرسومات)
ذاكرة الملف
في ما يلي إرشادات عامة بشأن الذاكرة الاحتياطية المستندة إلى ملف:
- بشكل عام، تتم إدارة ذاكرة الملفات بشكل جيد من خلال إدارة ذاكرة نظام التشغيل.
- ولم نجد أنّها سبب رئيسي لضغط الذاكرة في الوقت الحالي.
ومع ذلك، عند التعامل مع ذاكرة الملف بشكل عام:
- لا تضمِّن المكتبات غير المستخدَمة في الإصدار، واستخدِم مجموعات فرعية صغيرة من المكتبات بدلاً من المكتبات الكاملة كلما أمكن ذلك.
- لا تُبقِ الملفات الكبيرة مفتوحة في الذاكرة، وأغلِقها فور الانتهاء من استخدامها.
- تقليل حجم الرموز المجمَّعة لفئات Java وKotlin، راجِع دليل تقليص حجم تطبيقك وتعتيمه وتحسينه.
اقتراحات محدّدة بشأن المحتوى التلفزيوني
يقدّم هذا القسم اقتراحات محدّدة لتحسين استخدام الذاكرة على أجهزة التلفزيون.
ذاكرة الرسومات
استخدِم تنسيقات ودقة مناسبة للصور.
- لا تحمّل صورًا بدقة أعلى من دقة واجهة مستخدم الجهاز. على سبيل المثال، يجب تقليل حجم صور 1080p إلى 720p على جهاز واجهة مستخدم بدقة 720p.
- استخدِم صور نقطية مستنِدة إلى الأجهزة عند الإمكان.
- في المكتبات، مثل Glide، فعِّل الميزة
Downsampler.ALLOW_HARDWARE_CONFIGالتي تكون غير مفعّلة تلقائيًا. يؤدي تفعيل هذا الخيار إلى تجنُّب تكرار الصور النقطية التي ستكون في كلّ من ذاكرة الرسومات والذاكرة المجهولة.
- في المكتبات، مثل Glide، فعِّل الميزة
- تجنُّب عمليات العرض الوسيطة وعمليات إعادة العرض
- يمكن تحديد هذه المشاكل باستخدام Android GPU Inspector:
- ابحث في قسم "التركيبات" عن صور تمثّل خطوات نحو العرض النهائي بدلاً من أن تكون مجرد العناصر التي تشكّلها، ويُطلق على هذا النوع عادةً اسم "العرض الوسيط".
- بالنسبة إلى تطبيقات حزمة تطوير البرامج (SDK) لنظام التشغيل Android، يمكنك غالبًا إزالة هذه العروض باستخدام علامة التنسيق
forceHasOverlappedRendering:falseلإيقاف العروض الوسيطة لهذا التنسيق. - يمكنك الاطّلاع على تجنُّب عمليات العرض المتداخلة للحصول على معلومات مفيدة حول عمليات العرض المتداخلة.
- تجنَّب تحميل صور العناصر النائبة عند الإمكان، واستخدِم
@android:color/أو@colorلإنشاء نسيج العنصر النائب. - تجنَّب تركيب صور متعددة على الجهاز عندما يكون بإمكانك إجراء التركيب بلا إنترنت. تفضيل تحميل الصور المستقلة بدلاً من إنشاء تركيبة صور من الصور التي تم تنزيلها
- اتّبِع دليل التعامل مع الصور النقطية للتعامل بشكل أفضل مع الصور النقطية.
Anon+Swap memory
يتكوّن Anon+Swap من عمليات تخصيص الذاكرة الأصلية وJava وStack في أداة فحص الذاكرة في استوديو Android. استخدِم
ActivityManager.isLowMemoryDevice()
للتحقّق مما إذا كان الجهاز يعاني من قيود على الذاكرة، وتكيَّف مع هذا الوضع
باتّباع هذه الإرشادات.
- الوسائط:
- تحديد حجم متغير لمخازن وسائط مؤقتة استنادًا إلى ذاكرة الوصول العشوائي (RAM) في الجهاز ودقة تشغيل الفيديو يجب أن يمثّل ذلك دقيقة واحدة من تشغيل الفيديو:
- من 40 إلى 60 ميغابايت لكل غيغابايت / 1080p
- 60 إلى 80 ميغابايت لكل 1.5 غيغابايت / 1080p
- 80 إلى 100 ميغابايت مقابل 1.5 غيغابايت / 2160p
- 100 إلى 120 ميغابايت مقابل 2 غيغابايت / 2160p
- تحرير مساحة الذاكرة المخصّصة للوسائط المجانية عند تغيير حلقة لمنع حدوث زيادات في إجمالي مقدار الذاكرة المجهولة
- إصدار موارد الوسائط وإيقافها على الفور عند إيقاف تطبيقك: استخدِم عمليات رد الاتصال لدورة حياة النشاط للتعامل مع موارد الصوت والفيديو. إذا لم يكن تطبيقك تطبيقًا صوتيًا، عليك إيقاف التشغيل عند حدوث
onStop()في أنشطتك، وحفظ كل العمل الذي تقوم به، وضبط مواردك ليتم تحريرها. لجدولة العمل الذي قد تحتاجه لاحقًا راجِع قسم المهام والتنبيهات.- يمكنك استخدام المكوّنات المتوافقة مع مراحل النشاط،
مثل
LiveDataوLifecycleOwner، لمساعدتك في التعامل مع طلبات مراحل نشاط Activity. - لجعل عملك متوافقًا مع Lifecycle، يمكنك أيضًا استخدام الكوروتينات في Kotlin وتدفقات Kotlin.
- يمكنك استخدام المكوّنات المتوافقة مع مراحل النشاط،
مثل
- الانتباه إلى ذاكرة التخزين المؤقت عند البحث عن فيديو: يخصّص المطوّرون غالبًا ما بين 15 و60 ثانية إضافية من المحتوى المستقبلي عند البحث عن فيديو ليكون جاهزًا للمستخدم، ولكن يؤدي ذلك إلى زيادة في استخدام الذاكرة.
بشكل عام، لا تستخدم أكثر من 5 ثوانٍ من المخزن المؤقت المستقبلي إلى أن يختار المستخدم موضع الفيديو الجديد. إذا كنت بحاجة إلى التخزين المؤقت المسبق لمدة إضافية أثناء البحث، احرص على:
- خصِّص المخزن المؤقت للبحث مسبقًا وأعِد استخدامه.
- يجب ألا يزيد حجم ذاكرة التخزين المؤقت عن 15 إلى 25 ميغابايت (حسب ذاكرة الجهاز).
- تحديد حجم متغير لمخازن وسائط مؤقتة استنادًا إلى ذاكرة الوصول العشوائي (RAM) في الجهاز ودقة تشغيل الفيديو يجب أن يمثّل ذلك دقيقة واحدة من تشغيل الفيديو:
- عمليات التخصيص:
- استخدِم إرشادات ذاكرة الرسومات للتأكّد من أنّك لا تكرّر الصور في الذاكرة المجهولة
- غالبًا ما تكون الصور هي أكبر مستهلك للذاكرة، لذا يمكن أن يؤدي تكرارها إلى الضغط على الجهاز. ويكون ذلك صحيحًا بشكل خاص أثناء التنقّل المكثّف في طرق عرض شبكة الصور.
- إصدار عمليات التخصيص عن طريق إسقاط مراجعها عند نقل الشاشات: تأكَّد من عدم ترك أي مراجع لصور نقطية وكائنات.
- استخدِم إرشادات ذاكرة الرسومات للتأكّد من أنّك لا تكرّر الصور في الذاكرة المجهولة
- المكتبات:
- عمليات تخصيص ذاكرة الملف الشخصي من المكتبات عند إضافة مكتبات جديدة، إذ قد يتم تحميل مكتبات إضافية أيضًا، ما قد يؤدي أيضًا إلى عمليات تخصيص وإنشاء عمليات ربط.
- الاتصال بالشبكات:
- لا تُجرِ مكالمات الشبكة التي تحظر الوصول إلى البيانات أثناء بدء تشغيل التطبيق، لأنّها تؤدي إلى إبطاء وقت بدء تشغيل التطبيق وتزيد من استهلاك الذاكرة عند التشغيل، علمًا بأنّ الذاكرة تكون محدودة بشكل خاص بسبب تحميل التطبيق. اعرض شاشة تحميل أو شاشة البداية أولاً، وأرسِل طلبات الشبكة بعد اكتمال واجهة المستخدم.
عمليات الربط
عمليات الربط تتسبّب في زيادة الحمل الزائد للذاكرة لأنّها تستدعي تطبيقات أخرى إلى الذاكرة أو تزيد من استهلاك الذاكرة للتطبيق المرتبط (إذا كان التطبيق في الذاكرة بالفعل) لتسهيل طلب البيانات من واجهة برمجة التطبيقات. ونتيجةً لذلك، يقلل ذلك من الذاكرة المتاحة للتطبيق الذي يعمل في المقدّمة. وعند ربط خدمة، يجب الانتباه إلى وقت استخدام الربط ومدته. احرص على إلغاء الربط عندما لا تكون بحاجة إليه.
عمليات الربط النموذجية وأفضل الممارسات:
- واجهة برمجة التطبيقات Play Integrity API: تُستخدَم للتحقّق من
سلامة الجهاز
- التحقّق من سلامة الجهاز بعد شاشة التحميل وقبل تشغيل الوسائط
- يجب إيقاف مراجع PlayIntegrity
StandardIntegrityManagerقبل تشغيل المحتوى.
- مكتبة الفوترة في Play: تُستخدَم لإدارة الاشتراكات والمشتريات باستخدام
- Google Play
- يجب تهيئة المكتبة بعد شاشة التحميل، والتعامل مع جميع عمليات الفوترة قبل تشغيل أي وسائط.
- استخدِم
BillingClient.endConnection()عند الانتهاء من استخدام المكتبة وقبل تشغيل الفيديو أو الوسائط. - استخدِم
BillingClient.isReady()وBillingClient.getConnectionState()للتحقّق مما إذا تم قطع اتصال الخدمة في حال الحاجة إلى إعادة تنفيذ أي إجراءات متعلقة بالفوترة، ثم نفِّذBillingClient.endConnection()مرة أخرى بعد الانتهاء.
- GMS FontsProvider
- ننصح باستخدام خطوط مستقلة على الأجهزة ذات ذاكرة الوصول العشوائي المنخفضة بدلاً من استخدام موفّر الخطوط، لأنّ تنزيل الخطوط مكلف وسيتم ربط الخدمات بـ FontsProvider لتنفيذ ذلك.
- مكتبة مساعد Google: تُستخدم أحيانًا للبحث والبحث داخل التطبيق، لذا يجب استبدالها إذا أمكن.
- بالنسبة إلى تطبيقات leanback: استخدِم ميزة تحويل النص إلى كلام في Gboard أو مكتبة androidx.leanback.
- اتّبِع إرشادات "بحث Google" لتنفيذ البحث.
- ملاحظة: تم إيقاف leanback نهائيًا، ويجب نقل التطبيقات إلى TV Compose.
- بالنسبة إلى تطبيقات Compose:
- استخدِم ميزة "تحويل النص إلى كلام" في Gboard لتنفيذ البحث الصوتي.
- استخدِم ميزة المحتوى التالي لتسهيل عثور المستخدمين على المحتوى الإعلامي في تطبيقك.
- بالنسبة إلى تطبيقات leanback: استخدِم ميزة تحويل النص إلى كلام في Gboard أو مكتبة androidx.leanback.
الخدمات التي تعمل في المقدّمة
الخدمات التي تعمل في المقدّمة هي نوع خاص من الخدمات المرتبطة بإشعار. يظهر هذا الإشعار في لوحة الإشعارات على الهواتف والأجهزة اللوحية، ولكن أجهزة التلفزيون لا تتضمّن لوحة إشعارات بالمعنى نفسه. على الرغم من أنّ الخدمات التي تعمل في المقدّمة مفيدة لأنّه يمكن إبقاؤها قيد التشغيل أثناء عمل التطبيق في الخلفية، يجب أن تلتزم تطبيقات التلفزيون بالإرشادات التالية:
في Android TV وGoogle TV، يُسمح فقط للخدمات التي تعمل في المقدّمة بمواصلة العمل بعد أن يغادر المستخدم التطبيق، وذلك في الحالات التالية:
- بالنسبة إلى تطبيقات الصوت: يُسمح فقط للخدمات التي تعمل في المقدّمة بمواصلة العمل بعد أن يغادر المستخدم التطبيق، وذلك لمواصلة تشغيل المقطع الصوتي. يجب إيقاف الخدمة فورًا بعد انتهاء تشغيل الصوت.
- بالنسبة إلى أي تطبيق آخر: يجب إيقاف جميع الخدمات التي تعمل في المقدّمة. عندما يغادر المستخدم تطبيقك، لأنّه لا يوجد إشعار لإعلام المستخدم بأنّ التطبيق لا يزال يعمل ويستهلك الموارد.
- بالنسبة إلى المهام التي يتم تنفيذها في الخلفية مثل تعديل الاقتراحات أو المحتوى التالي، استخدِم
WorkManager.
الوظائف والمنبّهات
WorkManager
هي أحدث واجهة برمجة تطبيقات Android لجدولة المهام المتكررة التي يتم تنفيذها في الخلفية.
سيستخدم WorkManager JobScheduler الجديد عند توفّره (الإصدار 23 من حزمة تطوير البرامج (SDK) أو الإصدارات الأحدث) وAlarmManager القديم عند عدم توفّره. للحصول على أفضل الممارسات لتنفيذ المهام المجدوَلة على التلفزيون، يُرجى اتّباع التوصيات التالية:
- تجنَّب استخدام واجهات برمجة التطبيقات
AlarmManagerعلى الإصدار 23 من حزمة تطوير البرامج (SDK) أو الإصدارات الأحدث، خاصةًAlarmManager.set()وAlarmManager.setExact()والطُرق المشابهة، لأنّها لا تسمح للنظام بتحديد الوقت المناسب لتنفيذ المهام (على سبيل المثال، عندما يكون الجهاز في وضع الخمول). - على الأجهزة ذات ذاكرة الوصول العشوائي المنخفضة، تجنَّب تنفيذ المهام إلا إذا كان ذلك ضروريًا للغاية. إذا لزم الأمر، استخدِم WorkManager
WorkRequestفقط لتعديل الاقتراحات بعد التشغيل، وحاوِل إجراء ذلك أثناء بقاء التطبيق مفتوحًا. حدِّد WorkManager
Constraintsليتيح للنظام تنفيذ مهامك في الوقت المناسب:
Kotlin
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.setRequiresDeviceIdle(true)
.build()
Java
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.setRequiresDeviceIdle(true)
.build()
- إذا كان عليك تنفيذ المهام بانتظام (على سبيل المثال، لتعديل المحتوى التالي استنادًا إلى نشاط مشاهدة المحتوى لدى المستخدم في تطبيقك على جهاز آخر)، عليك إبقاء استخدام الذاكرة منخفضًا من خلال إبقاء استهلاك الذاكرة للمهمة أقل من 30 ميغابايت.
اعتبارات عامة بشأن الذاكرة
تقدّم الإرشادات التالية معلومات عامة حول تطوير تطبيقات Android:
- قلِّل عمليات تخصيص العناصر، وحسِّن إعادة استخدام العناصر، وألغِ تخصيص أي عناصر غير مستخدَمة على الفور.
- لا تحتفظ بمراجع للكائنات، خاصةً الصور النقطية.
- تجنَّب استخدام
System.gc()وطلبات تحرير الذاكرة المباشرة، لأنّها تتداخل مع عملية معالجة الذاكرة في النظام. على سبيل المثال، في الأجهزة التي تستخدم zRAM، يمكن أن يؤدي طلب إجباري إلىgc()إلى زيادة استخدام الذاكرة مؤقتًا بسبب ضغط الذاكرة وفك ضغطها. - استخدِم
LazyListكما هو موضّح في متصفّح الكتالوج في Compose أوRecyclerViewفي حزمة أدوات Leanback UI التي تم إيقافها نهائيًا، وذلك لإعادة استخدام طرق العرض وعدم إعادة إنشاء عناصر القائمة. - تخزين العناصر التي يتم قراءتها من موفّري المحتوى الخارجيين بشكل مؤقت على الجهاز، وهي العناصر التي من غير المحتمل أن تتغير، وتحديد فواصل زمنية للتحديث تمنع تخصيص ذاكرة خارجية إضافية
- تحقَّق من احتمال حدوث تسرُّب للذاكرة.
- انتبه إلى حالات تسريب الذاكرة النموذجية، مثل المراجع داخل سلاسل المحادثات المجهولة وإعادة تخصيص مخازن الفيديو المؤقتة التي لا يتم إصدارها أبدًا والحالات المشابهة الأخرى.
- استخدِم لقطة لأجزاء من الذاكرة لتصحيح أخطاء تسرُّب الذاكرة.
- يمكنك إنشاء ملفات تعريف أساسية لتقليل مقدار عملية الترجمة في الوقت المناسب المطلوبة عند تنفيذ تطبيقك عند تشغيله على البارد.
فهم عملية استرداد الذاكرة المباشرة
عندما يطلب أحد تطبيقات Android TV بيانات الذاكرة ويكون النظام تحت ضغط، قد يضطر نواة Linux، التي يستند إليها نظام التشغيل Android، إلى استخدام استرداد الذاكرة المباشر.
تتضمّن العملية إيقاف أي سلسلة تعليمات مخصّصة مؤقتًا للانتظار إلى أن يتم إخلاء صفحات الذاكرة. يحدث ذلك عندما لا تتمكّن عملية استرداد الذاكرة في الخلفية من الحفاظ على مجموعة كافية من الذاكرة بشكل استباقي.
ويمكن أن يؤدي ذلك إلى حدوث توقفات مؤقتة أو إيقاف مؤقت لعرض واجهة المستخدم ملحوظ في تجربة المستخدم، لأنّ النظام يوقف عملية تخصيص سلاسل التعليمات إلى أن تتوفّر مساحة كافية من الذاكرة. بهذا المعنى، لا يقتصر تخصيص سلاسل التعليمات على طلبات الرمز البرمجي للتطبيق، مثل malloc()، بل يجب تخصيص الذاكرة للصفحة في صفحات الرموز، على سبيل المثال.
ملخّص الأدوات
- استخدِم أداة أداة "محلّل الذاكرة" في "استوديو Android"
للتحقّق من استهلاك الذاكرة أثناء الاستخدام.
- استخدِم heapdump للتحقّق من عمليات تخصيص عناصر وصور نقطية معيّنة.
- استخدِم أداة تحليل الذاكرة الأصلية للتحقّق من عمليات التخصيص غير المتعلّقة بلغة Java أو Kotlin.
- استخدِم Android GPU Inspector للتحقّق من عمليات تخصيص الرسومات.