ניהול יעיל של הזיכרון במשחקים

בפלטפורמת Android, המערכת מנסה להשתמש בזיכרון מערכת (RAM) בנפח גדול ככל האפשר, ומבצע אופטימיזציות שונות של זיכרון כדי לפנות מקום במקרה הצורך. לאופטימיזציות האלה יכולה להיות השפעה שלילית על המשחק שלך, בגלל האטה או להרוג אותו לגמרי. מידע נוסף על האופטימיזציות האלה בנושא הקצאת זיכרון בין תהליכים.

בדף הזה מוסבר מה אפשר לעשות כדי להימנע מתנאים של מחסור בזיכרון שמשפיעים על המשחק.

תגובה ל-onTrimMemory()

המערכת משתמשת onTrimMemory() כדי להודיע לאפליקציה שהזיכרון עומד להיגמר וייתכן שהאפליקציה תפסיק לפעול. הרבה פעמים, זו האזהרה היחידה שהאפליקציה מקבלת. לשיחה החוזרת יש זמן אחזור ארוך ביחס low-memory killer (LMK), לכן חשוב מאוד להגיב במהירות לקריאה החוזרת.

בתגובה לקריאה החוזרת הזו, מפחיתים את המהירות, המספר והגודל של ההקצאות. הערך onTrimMemory() מעביר ערך קבוע שמציין את מידת החומרה, אבל כדאי להגיב לאזהרה הראשונה, כי ניתן להקצות מהר יותר onTrimMemory() יכול להגיב.

Kotlin

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
        }
    }
}

Java

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;

C#‎

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 Advantage API

ה-Memory Adwise API פותח ל-onTrimMemory, שיש לו רמת זיכרון גבוהה יותר ורמת דיוק גבוהה יותר חיזוי של מערכות LMK קרובות. ה-API משיג זאת על ידי הערכת כמות במשאבי זיכרון שנמצאים בשימוש, ולאחר מכן הודעות לאפליקציה כאשר פונקציות מסוימות יש חריגה מערכי הסף. ה-API יכול גם לדווח על האחוז המשוער של של הזיכרון ישירות באפליקציה. אפשר להשתמש ב-Memory Adwise API בתור חלופה ל- onTrimMemory אירועים לצורך ניהול זיכרון.

כדי להשתמש ב-Memory Advantage API צריך להשתמש המדריך לתחילת העבודה.

מקפידים על יכולות שמרניות של תקציבי זיכרון

תקציב תקציב נמוך באופן שמרני כדי למנוע מחסור בזיכרון. פריטים מסוימים כדאי לכלול את הנושאים הבאים:

  • גודל ה-RAM הפיזי: לעיתים קרובות, במשחקים נעשה שימוש ב-1⁄4 מ-1⁄2 מהזיכרון הפיזי. כמות ה-RAM במכשיר.
  • גודל zRAM מקסימלי: אם נפח האחסון גדול יותר, יכול להיות שלמשחק יהיה יותר זיכרון להקצות. הסכום הזה יכול להשתנות בהתאם למכשיר. צריך לחפש את SwapTotal ב- /proc/meminfo כדי למצוא את הערך הזה.
  • השימוש בזיכרון של מערכת ההפעלה: מכשירים שמקצים יותר RAM למערכת תהליכים משאירים פחות זיכרון למשחק. המערכת משביתה את המשחק לפני שהוא הורג תהליכים במערכת.
  • שימוש בזיכרון של אפליקציות מותקנות: בדיקת המשחק במכשירים שבהם יש הרבה האפליקציות שהותקנו. אפליקציות של רשתות חברתיות וצ'אט צריכות לפעול באופן רציף ולהשפיע כמות הזיכרון החופשי.

אם אתם לא יכולים להתחייב לתקציב זיכרון שמרני, קחו פסק זמן גמיש יותר . אם המערכת נתקלת בבעיות נפח זיכרון נמוך, עדיף לצמצם את כמות הזיכרון שהמשחק משתמש בהן. לדוגמה, להקצות טקסטורות ברזולוציה נמוכה יותר או לאחסן פחות תוכנות הצללה (shader) בתגובה ל-onTrimMemory(). הגישה הדינמית הזו לזיכרון ההקצאה דורשת יותר עבודה של המפתח, במיוחד בעיצוב המשחק שלב אחד.

נמנעים מהתעסקות במכשיר

זעזוע מתרחש כשהזיכרון הפנוי נמוך, אבל לא נמוך מספיק, כדי לסיים את המשחק. במצב הזה, kswapd דורש חזרה דפים שהמשחק עדיין צריך, כך מנסה לטעון מחדש את הדפים מהזיכרון. אין מספיק מקום, לכן הדפים ממשיכים להיות מוחלפים (החלפה רציפה). מעקב המערכת מדווח על המצב הזה כשרשור כאשר kswapd פועל ברצף.

אחד מהתסמינים של חנק הוא זמני מסגרות ארוכים - אולי שנייה או יותר. הקטנה את טביעת הרגל הפחמנית של המשחק כדי לפתור את המצב הזה.

שימוש בכלים הזמינים

ב-Android יש אוסף של כלים שעוזרים להבין איך המערכת שמנהל את הזיכרון.

מידע על זכרונות

הכלי הזה אוסף נתוני זיכרון כדי להראות כמה זיכרון PSS שהוקצתה לו והקטגוריות שבהן הוא היה בשימוש.

להדפיס את הנתונים הסטטיסטיים של meminfo באחד מ- בדרכים הבאות:

  • משתמשים בפקודה adb shell dumpsys meminfo package-name.
  • שימוש בקריאה ל-MemoryInfo מ-Android Debug API.

הנתון הסטטיסטיים של PrivateDirty מראה את כמות ה-RAM בתהליך שלא ניתן להעביר לדיסק ושאי אפשר לשתף אותו בכל תהליך אחר. רוב הסכום הזה יהיה זמין המערכת כשהתהליך הזה מאבד.

נקודות מעקב של זיכרון

נקודות מעקב של הזיכרון עוקבות אחר הכמות זיכרון RSS שבו המשחק משתמש. חישוב השימוש בזיכרון ב-RSS הרבה יותר מהיר מאשר חישוב שימוש ב-PSS. מאחר שהחישוב מהיר יותר, ה-RSS מציג רמת פירוט גבוהה יותר שינויים בגודל הזיכרון לצורך מדידות מדויקות יותר של שימוש שיא בזיכרון. לכן קל יותר להבחין בנקודות שיא שעלולות לגרום לכך שהמשחק ייגמר זיכרון.

פרפטו ועקבות ארוכים

Perfetto היא חבילת כלים לאיסוף מידע על הביצועים והזיכרון במכשיר, ומוצגים בממשק משתמש מבוסס-אינטרנט. הוא תומך במעקבים ארוכים באופן שרירותי, כדי שתוכלו לראות איך ה-RSS משתנה לאורך זמן. תוכלו גם ליצור שאילתות SQL על הנתונים שהוא מפיק לעיבוד אופליין. הפעלת מעקבים ארוכים אפליקציית System Tracing. צריך לוודא שהמאפיינים הקטגוריה memory:Memory מופעלת למעקב.

ערימה (heapprofd)

heapprofd הוא כלי למעקב אחרי זיכרון זה חלק מ-Perfetto. הכלי הזה יכול לעזור לך לאתר דליפות זיכרון על ידי הצגת שבו הזיכרון הוקצה באמצעות malloc. אפשר להתחיל להשתמש ב-heapprofd ב-Python, ומאחר שלכלי יש תקורה נמוכה, הוא לא משפיע ביצועים כמו כלים אחרים כמו Malloc Debug.

דוח על באג

bugreport הוא כלי לרישום ביומן כדי לברר אם המשחק קרס או לא כי נגמר לו הזיכרון. הפלט של הכלי מפורט הרבה יותר מאשר השימוש Logcat. היא שימושית לניפוי באגים בזיכרון כי היא מראה אם המשחק שלכם קרס כי נגמר לו הזיכרון או אם הוא נהרג על ידי המערכת לניהול למידה (LMK).

מידע נוסף זמין במאמר הבא: תיעוד וקריאה של דוחות על באגים.