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

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

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

پاسخ به onTrimMemory()

این سیستم از onTrimMemory() برای اطلاع‌رسانی به برنامه شما در مورد رویدادهای چرخه عمر استفاده می‌کند که فرصت خوبی را برای برنامه شما فراهم می‌کنند تا داوطلبانه میزان استفاده از حافظه خود را کاهش دهد و از کشته شدن توسط قاتل کم حافظه (LMK) برای آزاد کردن حافظه برای استفاده سایر برنامه‌ها جلوگیری کند.

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

هنگام پاسخ به رویدادهای trim، بهتر است تخصیص‌های حافظه بزرگی را که فوراً مورد نیاز نیستند و می‌توانند در صورت تقاضا بازسازی شوند، آزاد کنید. به عنوان مثال، اگر برنامه شما دارای حافظه پنهانی از بیت‌مپ‌هایی است که از تصاویر فشرده شده محلی رمزگشایی شده‌اند، اغلب ایده خوبی است که این حافظه پنهان را در پاسخ به TRIM_MEMORY_UI_HIDDEN trim یا پاک کنید.

کاتلین

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {
    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.
        }
    }
}

جاوا

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
    public void onTrimMemory(int level) {
        switch (level) {
            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.
            }
        }
    }
}

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

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

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

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

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

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

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

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

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

ممینفو

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

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

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

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

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

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

پرفتو و ردپاهای طولانی

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

تایید شده

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

گزارش اشکال

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

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