Panoramica della gestione della memoria

Android Runtime (ART) e la macchina virtuale Dalvik utilizzano la macchina virtuale paging e la mappatura della memoria (mmapping) per gestire la memoria. Ciò significa che qualsiasi ricordo di un'app o modifiche, sia allocando nuovi oggetti o toccare pagine mappate, rimane residente nella RAM e non possono essere impaginati. L'unico modo per liberare la memoria da un'app è rilasciare fa riferimento all'oggetto contenuto nell'app, rendendo la memoria disponibile garbage collector. C'è una sola eccezione: tutti i file mmappato senza modifiche, come codice, può essere scaricata dalla RAM se il sistema vuole usare altrove quella memoria.

In questa pagina viene spiegato in che modo Android gestisce i processi e la memoria delle app l'allocazione delle risorse. Per saperne di più su come gestire la memoria in modo più efficiente nella tua app, vedi Gestisci la memoria dell'app.

Garbage collection

Un ambiente di memoria gestito, come la macchina virtuale ART o Dalvik, tiene traccia di ogni allocazione di memoria. Una volta determinato che una porzione di memoria non sia più usata dal programma, lo libera nell'heap, senza alcun intervento da parte del programmatore. Meccanismo per recuperare la memoria inutilizzata in un ambiente di memoria gestito è nota come garbage collection. La garbage collection ha due obiettivi: Trovare oggetti dati in un programma a cui non sarà possibile accedere in futuro; e di recuperare le risorse usate da questi oggetti.

L'heap di memoria di Android è generazionale, il che significa che diversi bucket di allocazioni monitorate, in base alla durata e alle dimensioni previste di un oggetto allocato. Ad esempio, gli oggetti allocati di recente appartengono alla generazione giovane. Quando un oggetto rimane attivo per un tempo sufficiente, può essere promosso a una generazione precedente, seguita da una generazione permanente.

Ogni generazione di heap ha il proprio limite superiore dedicato di memoria che gli oggetti possono occupare. Ogni volta che inizia una generazione il sistema esegue una garbage collection nel tentativo di liberare memoria. Durata della garbage collection dipende dalla generazione di oggetti che raccoglie e il numero di oggetti attivi in ogni generazione.

Anche se la garbage collection può essere piuttosto veloce, può influire sulle prestazioni della tua app. In genere non controlli quando si verifica un evento di garbage collection dall'interno del codice. Il sistema dispone di una serie di criteri per determinare quando eseguire garbage collection. Una volta soddisfatti i criteri, il sistema interrompe l'esecuzione del processo e avvia la garbage collection. Se La garbage collection avviene nel mezzo di un loop di elaborazione intensivo come un'animazione o durante la riproduzione di musica, possono aumentare i tempi di elaborazione. Questo aumento può potenzialmente portare l'esecuzione di codice nella tua app oltre soglia consigliata di 16 ms per un rendering efficiente e fluido dei frame.

Inoltre, il flusso del codice può svolgere tipi di operazioni che forzano eventi di garbage collection o farli durare più a lungo del normale. Ad esempio, se assegni più oggetti nel tag la parte più interna di un for-loop durante ogni frame di un alpha unendo l'animazione, potresti inquinare la tua memoria con una molti oggetti. In questo caso, il garbage collector esegue più garbage collection di raccolta dei dati e possono peggiorare le prestazioni della tua app.

Per informazioni più generali sulla garbage collection, consulta Raccolta dei rifiuti.

Condividi ricordo

Per includere tutto ciò di cui ha bisogno nella RAM, Android cerca di condividere le pagine RAM tra i processi. it puoi farlo nei seguenti modi:

  • Ogni processo dell'app viene creato tramite fork da un processo esistente chiamato Zygote. Il processo Zygote si avvia quando il sistema si avvia e carica il codice e le risorse del framework ad esempio i temi delle attività. Per avviare una nuova procedura per l'app: il sistema crea un fork del processo Zygote carica ed esegue il codice dell'app nel nuovo processo. Questo approccio consente alla maggior parte delle pagine RAM allocate, e le risorse del framework da usare in tutti i processi dell'app.
  • La maggior parte dei dati statici viene inserita in un processo. Questa tecnica consente di condividere i dati tra i processi e consente anche di impaginarli quando serve. Ecco alcuni esempi di dati statici: Codice Dalvik (inserendolo in un elemento .odex precollegato file per la mmapping diretto), risorse app (progettando la tabella delle risorse come una struttura che possono essere mmapp e allineando il file dell'APK) e le voci del progetto come il codice nativo nei file .so.
  • In molti paesi, Android condivide la stessa dinamica RAM per più processi utilizzando allocato esplicitamente regioni di memoria condivisa (con ashmem o gralloc). Ad esempio, le piattaforme delle finestre usano tra l'app e il compositore dello schermo, i buffer del cursore utilizzano la memoria condivisa fornitore di contenuti e client.

A causa dell'ampio uso della memoria condivisa, determinare la quantità di memoria utilizzata dalla tua app richiede cura. Tecniche per determinare correttamente la dell'uso della memoria sono trattati nel Analisi dell'utilizzo della RAM.

Alloca e recupera memoria dell'app

Il cumulo di Dalvik è vincolato a un un singolo intervallo di memoria virtuale per ogni processo dell'app. Questo definisce la dimensione logica dell'heap, che può aumentare in base alle esigenze ma solo entro un limite definito dal sistema per ogni app.

Le dimensioni logiche dell'heap non corrispondono a la quantità di memoria fisica utilizzata dall'heap. Durante l'ispezione dell'heap della tua app, Android calcola un valore chiamato Proportional Set Size (PSS), che tiene conto sia delle pagine sporche che pulite condivisi con altri processi, ma solo in un proporzionale al numero di app che condividono quella RAM. Il totale (PSS) è l'aspetto che il sistema sia la tua memoria fisica. Per ulteriori informazioni sui PSS, consulta Analisi dell'utilizzo della RAM guida.

L'heap di Dalvik non compatta la logica dimensioni dell'heap, il che significa che Android deframmentare l'heap per chiudere lo spazio. Android può ridurre le dimensioni logiche dell'heap solo quando spazio inutilizzato alla fine dell'heap. Tuttavia, il sistema può comunque ridurre la memoria fisica usata dall'heap. Dopo la garbage collection, Dalvik percorre l'heap e trova le pagine inutilizzate, poi restituisce quelle pagine al kernel usando madvise. Quindi, accoppiato allocazioni e deal di attività i blocchi dovrebbero comportare la rivendicazione di tutti (o quasi) la memoria fisica utilizzata. Tuttavia, recuperare la memoria da allocazioni ridotte può essere è meno efficiente perché la pagina utilizzava per una piccola allocazione possono essere qualcos'altro che non è stato ancora liberato.

Limita memoria app

Per mantenere un ambiente multitasking funzionale, Android imposta un limite rigido per la dimensione heap per ogni app. Il limite esatto delle dimensioni dell'heap varia tra i dispositivi in base alla quantità di RAM del dispositivo a disposizione in generale. Se la tua app ha raggiunto della capacità heap e prova ad allocarne memoria, può ricevere un OutOfMemoryError.

In alcuni casi, potresti voler eseguire una query per determinare esattamente quanto spazio heap disponibili sul dispositivo corrente, ad esempio per determinare la quantità di dati sicura da conservare . Puoi eseguire una query sul sistema per questa cifra richiamando getMemoryClass(). Questo metodo restituisce un numero intero che indica il numero di disponibili per l'heap dell'app.

Cambio di app

Quando gli utenti passano da un'app all'altra, Android mantiene le app non sono in primo piano, ovvero non sono visibili all'utente o stanno eseguendo servizi in primo piano come la riproduzione di musica: in una cache. Ad esempio, quando un utente avvia un'app per la prima volta, viene creato un processo; ma quando l'utente esce dall'app, la procedura non viene chiusa. Il sistema conserva il processo nella cache. Se l'utente torna all'app in un secondo momento, il sistema riutilizza il processo, velocizzando il passaggio da un'app all'altra.

Se la tua app dispone di un processo nella cache e conserva le risorse di cui attualmente non ha bisogno, l'app, anche quando l'utente non la usa, influisce sulla capacità del sistema il rendimento complessivo. Poiché il sistema sta esaurendo le risorse come la memoria, termina i processi nella cache. Inoltre, il sistema prende in considerazione i processi che contengono la maggior parte e può terminarle per liberare RAM.

Nota: minore è il consumo di memoria da parte dell'app quando si trova nella cache, maggiori sono le probabilità di non essere ucciso e di poter riprendere rapidamente. Tuttavia, a seconda dei requisiti di sistema istantanei, è possibile che la cache e i processi vengono terminati in qualsiasi momento, a prescindere dall'utilizzo delle risorse.

Per ulteriori informazioni su come i processi vengono memorizzati nella cache non vengono eseguiti in primo piano e come È Android a decidere quali possono essere uccisi, Processi e thread guida.

Test di stress della memoria

Sebbene i problemi di stress della memoria siano meno comuni sui dispositivi di fascia alta, possono comunque causare problemi per gli utenti che usano dispositivi con poca RAM, ad esempio quelli con Android Go. È importante provare a riprodurre questo ambiente con stress di memoria in modo da poter scrivere test di strumentazione per verificare l'app e migliorare l'esperienza degli utenti che usano dispositivi con memoria ridotta.

Test di applicazione stressante

Stressful Application Test (stressapptest) [Test delle applicazioni stressanti] è un test dell'interfaccia di memoria che aiuta a creare situazioni realistiche e con un carico elevato per testare vari tipi di memoria e limitazioni hardware per la tua app. Grazie alla capacità di definire limiti di tempo e memoria, consente di scrivere la strumentazione per verificare incontri nel mondo reale di situazioni con memoria elevata. Ad esempio, utilizza la seguente serie di comandi per eseguire il push della libreria statica nel tuo file system di dati: rendilo eseguibile ed esegui un test di stress per 20 secondi di 990 MB:
    adb push stressapptest /data/local/tmp/
    adb shell chmod 777 /data/local/tmp/stressapptest
    adb shell /data/local/tmp/stressapptest -s 20 -M 990

  

Consulta la stressapptest documentazione per ulteriori informazioni sull'installazione dello strumento, argomenti comuni e gestione degli errori informazioni.

Osservazioni su stressapptest

È possibile usare strumenti come stressapptest per richiedere allocazioni di memoria maggiori di quelle liberamente disponibili. Questo tipo di richiesta può generare vari avvisi di cui dovresti essere a conoscenza nel dal lato dello sviluppo. Tre avvisi principali che possono essere generati a causa di una scarsa disponibilità di memoria includono:
  • SIGABRT: Si tratta di un arresto anomalo nativo irreversibile per il tuo processo a causa della richiesta di allocazioni di maggiore della memoria libera, mentre il sistema è già sottoposto a pressione.
  • SIGQUIT: Genera un dump della memoria di base e termina il processo quando viene rilevato dal test di strumentazione.
  • TRIM_MEMORY_EVENTS: Questi callback sono disponibili su Android 4.1 (livello API 16) e versioni successive e forniscono di memoria per il processo.