Gestisci la memoria in modo efficace nei giochi

Sulla piattaforma Android, il sistema tenta di utilizzare la quantità di memoria di sistema (RAM) necessaria possibile ed esegue varie ottimizzazioni della memoria per liberare spazio quando necessario. Queste ottimizzazioni possono avere un effetto negativo sul gioco, sia rallentando lo butta giù o lo uccide del tutto. Puoi scoprire di più su queste ottimizzazioni sull'argomento Allocazione della memoria tra i processi.

In questa pagina vengono illustrati i passaggi da seguire per evitare condizioni di memoria insufficiente che interessano il tuo gioco.

Rispondere a onTrimMemory()

Il sistema utilizza onTrimMemory() per informare l'app che la memoria sta per esaurirsi e che l'app potrebbe essere terminata. Molte volte, questo è l'unico avviso ricevuto dalla tua app. Questo callback ha una latenza elevata rispetto ai uccisione a bassa memoria (LMK), quindi è fondamentale rispondere rapidamente alla chiamata.

In risposta a questo callback, riduci la velocità, il numero e la dimensione delle allocazioni. onTrimMemory() trasmette una costante che indica la gravità, ma dovresti rispondi al primo avviso perché è possibile assegnare più rapidamente onTrimMemory() può reagire.

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

Usa la versione beta dell'API Memory Advice

L'API Memory Advice è stata sviluppata come un'alternativa a onTrimMemory che ha un richiamo e una precisione molto più elevati che prevede LMK imminenti. L'API raggiunge questo risultato stimando la quantità di risorse di memoria in uso e di inviare una notifica all'app quando soglie. L'API può anche segnalare la percentuale stimata di memoria utilizzata direttamente nell'app. Puoi usare l'API Memory Advice come alternativa a onTrimMemory per la gestione della memoria.

Per utilizzare l'API Memory Advice utilizza il metodo Guida introduttiva.

Adotta un approccio conservativo con i budget per la memoria

Adotta un budget prudente per la memoria per evitare di esaurire la memoria. Alcuni elementi a considera di includere quanto segue:

  • Dimensione della RAM fisica: i giochi utilizzano spesso da 1⁄4 a 1⁄2 della RAM fisica Quantità di RAM sul dispositivo.
  • Dimensione massima zRAM: più zRAM significa che il gioco potrebbe avere più memoria da allocare. Questo importo può variare in base al dispositivo. cerca SwapTotal in /proc/meminfo per trovare questo valore.
  • Utilizzo della memoria del sistema operativo: dispositivi che utilizzano più RAM per il sistema lasciano meno memoria per il tuo gioco. Il sistema termina prima che termini i processi di sistema.
  • Utilizzo della memoria delle app installate: testa il gioco sui dispositivi che hanno molte di Google Cloud. Le app di social media e di chat devono essere costantemente eseguite e incidono la quantità di memoria libera.

Se non puoi impegnarti a un budget conservativo per la memoria, prendi in considerazione l'importanza di un approccio umile. Se nel sistema si verificano problemi di memoria insufficiente, riduci la quantità di memoria. usata dal gioco. Ad esempio, alloca texture o archivia Shader in meno in risposta all'evento onTrimMemory(). Questo approccio dinamico alla memoria richiede un maggiore impegno da parte dello sviluppatore, soprattutto nella progettazione del gioco durante la fase di sviluppo.

Evita il thrashing

Il thrashing si verifica quando la memoria libera è scarsa, ma non abbastanza da poter terminare il gioco. In questa situazione, kswapd ha rivendicato delle pagine di cui il gioco ha ancora bisogno, quindi cerca di ricaricare le pagine dalla memoria. Lo spazio non è sufficiente, pertanto le pagine continuano a essere scambiati (scambio continuo). Il tracciamento del sistema segnala questa situazione come thread in cui kswapd viene eseguito continuamente.

Un sintomo del thrashing è la durata dell'inquadratura, ad esempio un secondo o più. Riduci l'impronta di memoria del gioco per risolvere la situazione.

Utilizzare gli strumenti disponibili

Android offre una raccolta di strumenti per aiutare a comprendere in che modo il sistema gestisce la memoria.

Meminfo

Questo strumento raccoglie le statistiche relative alla memoria per mostrare Memoria PSS è stato assegnato e le categorie per cui è stato utilizzato.

Stampa le statistiche meminfo in una delle nei seguenti modi:

  • Utilizza il comando adb shell dumpsys meminfo package-name.
  • Utilizza la chiamata MemoryInfo dell'API Android Debug.

La statistica PrivateDirty mostra quantità di RAM all'interno del processo che non può essere impaginata su disco e non viene condivisa con qualsiasi altro processo. La maggior parte di questo importo diventa disponibile per quando il processo viene interrotto.

Tracce di memoria

I tracepoint della memoria tracciano la quantità Memoria RSS usato dal gioco. Il calcolo dell'utilizzo della memoria RSS è molto più veloce rispetto al calcolo Utilizzo PSS. Poiché è più veloce da calcolare, il feed RSS mostra una granularità maggiore variazioni delle dimensioni della memoria per misurazioni più precise dei picchi di utilizzo della memoria. Pertanto, è più facile notare picchi che potrebbero causare l'esaurimento dello la memoria.

Perfetto e tracce lunghe

Perfetto è una suite di strumenti per la raccolta informazioni su prestazioni e memoria su un dispositivo e visualizzate in un'interfaccia utente basata sul web. Supporta tracce arbitrariamente lunghe, in modo da poter visualizzare come cambia il feed RSS nel tempo. Puoi anche eseguire query SQL sui dati che produce per l'elaborazione offline. Abilita tracce lunghe dal App di tracciamento del sistema. Assicurati che La categoria memory:Memory è abilitata per la traccia.

prof.heap

heapprofd è uno strumento di monitoraggio della memoria che fa parte di Perfetto. Questo strumento può aiutarti a trovare le fughe di memoria mostrandoti in cui è stata allocata la memoria utilizzando malloc. Puoi iniziare a utilizzare heapprofd utilizzando un dello script Python e, poiché lo strumento ha un overhead ridotto, non influisce come il debug di Malloc.

segnalazione di bug

bugreport è uno strumento di logging che consente di sapere se il gioco si è arrestato in modo anomalo perché ha esaurito la memoria. L'output dello strumento è molto più dettagliato rispetto all'utilizzo logcat. È utile per il debug della memoria perché mostra se il gioco ha subito un arresto anomalo. perché ha esaurito la memoria o se è stato ucciso dall'LMK.

Per ulteriori informazioni, vedi Acquisisci e leggi le segnalazioni di bug.