مدیریت موثر حافظه در بازی ها

در پلتفرم اندروید، سیستم سعی می‌کند تا حد امکان از حافظه سیستم (RAM) استفاده کند و بهینه‌سازی‌های مختلف حافظه را انجام می‌دهد تا در صورت نیاز فضا را آزاد کند. این بهینه‌سازی‌ها می‌توانند بر روی بازی شما تأثیر منفی بگذارند، چه با کند کردن آن یا از بین بردن آن. می توانید در مبحث تخصیص حافظه در میان فرآیندها درباره این بهینه سازی ها بیشتر بدانید.

این صفحه مراحلی را توضیح می‌دهد که می‌توانید برای جلوگیری از تأثیر شرایط حافظه کم بر بازی خود انجام دهید.

پاسخ به onTrimMemory()

سیستم از onTrimMemory() استفاده می کند تا به برنامه شما اطلاع دهد که حافظه در حال اتمام است و ممکن است برنامه از بین برود. بسیاری از اوقات، این تنها هشداری است که برنامه شما دریافت می کند. این تماس برگشتی نسبت به کشنده حافظه کم (LMK) تأخیر بالایی دارد، بنابراین پاسخ سریع به پاسخ به تماس ضروری است.

در پاسخ به این تماس، سرعت، تعداد و اندازه تخصیص ها را کاهش دهید. onTrimMemory() یک ثابت می دهد که شدت را نشان می دهد، اما باید به اولین هشدار پاسخ دهید زیرا امکان تخصیص سریعتر از آنچه onTrimMemory() می تواند به آن واکنش نشان دهد، وجود دارد.

کاتلین

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {
    override fun onTrimMemory(level: Int) {
        when (level) {
            ComponentCallbacks2.TRIM_MEMORY_MODERATE,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> // Respond to low memory condition
            else -> Unit
        }
    }
}

جاوا

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
    public void onTrimMemory(int level) {
        switch (level) {
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
              // Respond to low memory condition
                break;
            default:
                break;

سی شارپ

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

class LowMemoryTrigger : MonoBehaviour
{
    private void Start()
    {
        Application.lowMemory += OnLowMemory;
    }
    private void OnLowMemory()
    {
        // Respond to low memory condition (e.g., Resources.UnloadUnusedAssets())
    }
}

از Memory Advice API بتا استفاده کنید

Memory Advice API به عنوان جایگزینی برای onTrimMemory توسعه داده شد که یادآوری و دقت بسیار بالاتری در پیش‌بینی LMK‌های قریب‌الوقوع دارد. API با تخمین مقدار منابع حافظه در حال استفاده، و سپس اطلاع دادن به برنامه در صورت تجاوز از آستانه های خاص، به این امر دست می یابد. API همچنین می تواند درصد تخمینی استفاده از حافظه را مستقیماً به برنامه شما گزارش دهد. می توانید از Memory Advice API به عنوان جایگزینی برای رویدادهای onTrimMemory برای مدیریت حافظه استفاده کنید.

برای استفاده از Memory Advice API از راهنمای شروع استفاده کنید.

در مورد بودجه حافظه محافظه کار باشید

برای جلوگیری از تمام شدن حافظه، حافظه بودجه را محافظه کارانه تنظیم کنید. برخی از مواردی که باید در نظر گرفته شود شامل موارد زیر است:

  • اندازه رم فیزیکی : بازی ها اغلب بین ¼ تا ½ مقدار رم فیزیکی دستگاه استفاده می کنند.
  • حداکثر اندازه zRAM : zRAM بیشتر به این معنی است که بازی به طور بالقوه حافظه بیشتری برای تخصیص دارد. این مقدار می تواند بر اساس دستگاه متفاوت باشد. به دنبال SwapTotal در /proc/meminfo بگردید تا این مقدار را پیدا کنید.
  • استفاده از حافظه سیستم عامل : دستگاه هایی که رم بیشتری را برای پردازش های سیستم تعیین می کنند، حافظه کمتری برای بازی شما باقی می گذارند. این سیستم قبل از اینکه فرآیندهای سیستم را از بین ببرد، روند بازی شما را از بین می برد.
  • استفاده از حافظه برنامه‌های نصب‌شده : بازی خود را روی دستگاه‌هایی که برنامه‌های زیادی نصب شده‌اند آزمایش کنید. برنامه های رسانه های اجتماعی و چت باید دائما اجرا شوند و بر میزان حافظه آزاد تأثیر بگذارند.

اگر نمی توانید متعهد به بودجه محافظه کارانه حافظه باشید، رویکرد انعطاف پذیرتری را در پیش بگیرید. اگر سیستم با مشکلات حافظه کم مواجه شد، مقدار حافظه ای را که بازی استفاده می کند کاهش دهید. به عنوان مثال، در پاسخ به onTrimMemory() ، بافت‌های با وضوح پایین‌تر را اختصاص دهید یا سایه‌زن‌های کمتری ذخیره کنید. این رویکرد پویا برای تخصیص حافظه به کار بیشتر توسعه دهنده، به ویژه در مرحله طراحی بازی، نیاز دارد.

از کوبیدن خودداری کنید

Thrashing زمانی اتفاق می‌افتد که حافظه آزاد کم باشد، اما آنقدر کم نیست که بازی را از بین ببرد. در این شرایط، kswapd صفحاتی را که بازی هنوز به آنها نیاز دارد، بازیابی کرده است، بنابراین سعی می کند صفحات را از حافظه بارگذاری مجدد کند. فضای کافی وجود ندارد، بنابراین صفحات به طور مداوم تعویض می شوند (تبادل مداوم). ردیابی سیستم این وضعیت را به عنوان یک رشته که kswapd به طور مداوم در آن اجرا می شود گزارش می کند.

یکی از علائم کوبیدن زمان فریم طولانی است - احتمالاً یک ثانیه یا بیشتر. برای حل این وضعیت، ردپای حافظه بازی را کاهش دهید.

از ابزارهای موجود استفاده کنید

اندروید مجموعه ای از ابزارها برای کمک به درک نحوه مدیریت حافظه توسط سیستم دارد.

Meminfo

این ابزار آمار حافظه را جمع آوری می کند تا نشان دهد که چه مقدار حافظه PSS اختصاص داده شده است و چه دسته هایی از آن استفاده شده است.

آمار meminfo را به یکی از روش های زیر چاپ کنید:

  • از دستور adb shell dumpsys meminfo package-name استفاده کنید.
  • از تماس MemoryInfo از Android Debug API استفاده کنید.

آمار PrivateDirty میزان RAM داخل فرآیند را نشان می دهد که نمی توان آن را در دیسک صفحه بندی کرد و با هیچ فرآیند دیگری به اشتراک گذاشته نمی شود. بخش عمده ای از این مقدار زمانی در دسترس سیستم قرار می گیرد که این فرآیند از بین برود.

نقاط ردیابی حافظه

نقاط ردیابی حافظه میزان حافظه RSS مورد استفاده بازی شما را ردیابی می کنند. محاسبه میزان مصرف حافظه RSS بسیار سریعتر از محاسبه مصرف PSS است. از آنجایی که محاسبه سریع‌تر است، RSS جزئیات دقیق‌تری را در تغییرات اندازه حافظه نشان می‌دهد تا اندازه‌گیری دقیق‌تری از حداکثر استفاده از حافظه داشته باشد. بنابراین، مشاهده پیک‌هایی که می‌توانند باعث تمام شدن حافظه بازی شوند، آسان‌تر است.

پرفتو و آثار طولانی

Perfetto مجموعه ای از ابزارها برای جمع آوری اطلاعات عملکرد و حافظه روی یک دستگاه و نمایش در یک رابط کاربری مبتنی بر وب است. از ردیابی های طولانی خودسرانه پشتیبانی می کند تا بتوانید نحوه تغییر RSS در طول زمان را مشاهده کنید. همچنین می توانید پرس و جوهای SQL را روی داده هایی که برای پردازش آفلاین تولید می کند، صادر کنید. ردیابی طولانی را از برنامه System Tracing فعال کنید. مطمئن شوید که دسته حافظه: حافظه برای ردیابی فعال باشد.

heappropd

heapprofd یک ابزار ردیابی حافظه است که بخشی از Perfetto است. این ابزار می تواند با نشان دادن محل تخصیص حافظه با استفاده از malloc به شما کمک کند نشت حافظه را پیدا کنید. heapprofd می توان با استفاده از اسکریپت پایتون شروع کرد و چون این ابزار سربار کمی دارد، مانند ابزارهای دیگر مانند Malloc Debug بر عملکرد تأثیر نمی گذارد.

گزارش اشکال

bugreport ابزاری است برای یافتن اینکه آیا بازی شما به دلیل تمام شدن حافظه از کار افتاده است یا خیر. خروجی ابزار بسیار دقیق تر از استفاده از logcat است. این برای اشکال زدایی حافظه مفید است زیرا نشان می دهد که آیا بازی شما به دلیل تمام شدن حافظه از کار افتاده است یا اینکه توسط LMK کشته شده است.

برای اطلاعات بیشتر، به ضبط و خواندن گزارش‌های اشکال مراجعه کنید.