Avvisi sulla memoria del sistema operativo iPhone. Cosa significano i diversi livelli?


85

Per quanto riguarda l'arte nera di gestire la memoria su dispositivi iPhone OS: cosa significano i diversi livelli di avviso di memoria. Livello 1? Livello 2? Il quadrante va a 11?

Contesto: dopo un lungo periodo di stress test della memoria, incluso l'esecuzione della mia app per iPad con l'app del lettore musicale per iPod in riproduzione, sono incline a ignorare gli avvisi di memoria casuali ma poco frequenti che ricevo. La mia app non si arresta mai . Mai. La mia app è priva di perdite. E, beh, gli avvertimenti sui mems non sembrano avere importanza.

Grazie,
Doug

Risposte:


98

Fondamentalmente gli avvertimenti indicano che il dispositivo sta esaurendo la memoria e che "Se potessi liberare un po 'di memoria che non stai utilizzando attivamente, sarebbe fantastico! ". Se la tua gestione della memoria è limitata e non hai oggetti che potrebbero essere praticamente scartati, passa semplicemente il messaggio e ignoralo.


25
LOL "Se potessi per favore liberare un po 'di memoria che non stai utilizzando attivamente, sarebbe fantastico!"
Impagabile

15
Sembri un veterano grissinato del ballo della memoria wack-a-mole di iPhone OS.
dugla

193

Gli avvisi sul livello di memoria vengono registrati da SpringBoard. In qualità di sviluppatore di app, non devi preoccupartene. Basta rispondere a -{application}didReceiveMemoryWarningè sufficiente.


Sono disponibili 4 livelli di avvertenza (da 0 a 3). Questi sono impostati dal watcher della memoria del kernel e possono essere ottenuti dalla funzione not-so-publicOSMemoryNotificationCurrentLevel() .

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

Il modo in cui i livelli vengono attivati ​​non è documentato. SpringBoard è configurato per eseguire le seguenti operazioni in ogni livello di memoria:

  1. Avviso (non normale): riavvia o ritarda il riavvio automatico delle app in background non essenziali, ad esempio Mail.
  2. Urgente - Esci da tutte le app in background, ad esempio Safari e iPod.
  3. Critico e oltre - Il kernel prenderà il sopravvento, probabilmente uccidendo SpringBoard o addirittura riavviandosi.

L'uccisione dell'app attiva (jetsam) non è gestita da SpringBoard, ma launchd.


Grazie per questo. È stato un litigio tra te e Williham il comico su questa domanda. L'umorismo vince. Saluti.
dugla

Ciao, ho lo stesso problema. Dopo aver eseguito l'applicazione ininterrottamente per più di 5 volte, ricevo l'avviso di memoria ricevuta. Livello = 1 per 20 volte, ma l'applicazione non si arresta in modo anomalo. Ma quando ricevo questo messaggio, Ricevo avviso di memoria. Livello = 2 la mia applicazione si blocca. Il livello 2 viene visualizzato dopo il livello 1 per quasi 20 volte. Come posso fare in modo che la mia applicazione non si blocchi. Grazie
srikanth rongali,

1
@ Kenny: Meno memoria significa, quanto possiamo usare al massimo. Quanto possiamo avere byte live. Nel mio registro degli arresti anomali ho ricevuto questo. Pagine libere: 371 Pagine cablate: 12192 Pagine eliminabili: 0 Processo più grande: DTMobileIS Cosa significa? Dove dovrei prendermi cura? Grazie.
srikanth rongali

9
@srik: Faresti meglio a fare una nuova domanda .
kennytm

@kennytm: è ancora possibile con ios8? Ho visto che la funzione è definita in libsystem_c.dylib. Sarebbe fantastico se potessi andare avanti e usarlo. Grazie
focs

12

Da OSMemoryNotification.h ,

/*
** Threshold values for notifications
*/

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

totale 5 livelli di avviso di memoria (-1,3).

Per quanto riguarda la descrizione dell'avviso sul livello di memoria, la risposta di @ KennyTM è eccellente.

Voglio aggiungere diversi punti correlati che possono aiutare PM e altri.


Cosa dovresti fare quando hai un avviso sul livello di memoria?

Dopo aver ricevuto uno di questi avvisi, il metodo del gestore dovrebbe rispondere liberando immediatamente tutta la memoria non necessaria. Ad esempio, il comportamento predefinito della classe UIViewController consiste nell'eliminare la sua vista se quella vista non è attualmente visibile; le sottoclassi possono integrare il comportamento predefinito eliminando strutture di dati aggiuntive. Un'app che mantiene una cache di immagini potrebbe rispondere rilasciando tutte le immagini che non sono attualmente sullo schermo.


Come osservare l'avviso del livello di memoria?

Da http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html

Quando il sistema invia un avviso di memoria insufficiente alla tua app, rispondi immediatamente. iOS avvisa tutte le app in esecuzione ogni volta che la quantità di memoria libera scende al di sotto di una soglia di sicurezza. (Non notifica le app sospese.) Se la tua app riceve questo avviso, deve liberare quanta più memoria possibile. Il modo migliore per farlo è rimuovere i riferimenti forti a cache, oggetti immagine e altri oggetti dati che possono essere ricreati in seguito.

UIKit offre diversi modi per ricevere avvisi di memoria insufficiente, inclusi i seguenti:

  • Implementa il metodo applicationDidReceiveMemoryWarning: del tuo delegato dell'app.
  • Sostituisci il metodo didReceiveMemoryWarning nella tua sottoclasse UIViewController personalizzata.
  • Registrati per ricevere la notifica UIApplicationDidReceiveMemoryWarningNotification.

Come ridurre l'impronta di memoria della tua app?

  • Elimina le perdite di memoria.
  • Rendi i file di risorse più piccoli possibile.
  • Usa Core Data o SQLite per set di dati di grandi dimensioni.
  • Carica le risorse pigramente.
  • Crea il tuo programma utilizzando l'opzione Thumb.

Dettagli su http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html


Come allocare la memoria con saggezza?

  • Riduci l'uso di oggetti rilasciati automaticamente: con il conteggio automatico dei riferimenti (ARC), è meglio allocare / inizializzare gli oggetti e lasciare che il compilatore li rilasci al momento opportuno. Questo è vero anche per gli oggetti temporanei che in passato potresti essere stato rilasciato automaticamente per impedire loro di vivere oltre l'ambito del metodo corrente.
  • Imponi limiti di dimensione sulle risorse : evita di caricare un file di risorse di grandi dimensioni quando ne andrà uno più piccolo. Invece di utilizzare un'immagine ad alta risoluzione, utilizzane una di dimensioni adeguate per i dispositivi basati su iOS. Se devi utilizzare file di risorse di grandi dimensioni, trova i modi per caricare solo la parte del file di cui hai bisogno in un dato momento. Ad esempio, invece di caricare l'intero file in memoria, usa le funzioni mmap e munmap per mappare parti del file dentro e fuori la memoria. Per ulteriori informazioni sulla mappatura dei file in memoria.
  • Evita insiemi di problemi illimitati : gli insiemi di problemi illimitati potrebbero richiedere una quantità arbitrariamente grande di dati da calcolare. Se il set richiede più memoria di quella disponibile, l'app potrebbe non essere in grado di completare i calcoli. Le tue app dovrebbero evitare tali set quando possibile e lavorare su problemi con limiti di memoria noti.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.