Advertencias de memoria del iPhone OS. ¿Qué significan los diferentes niveles?

85

Con respecto al arte negro de administrar la memoria en dispositivos iPhone OS: ¿qué significan los diferentes niveles de advertencia de memoria? ¿Nivel 1? ¿Nivel 2? ¿El dial va a las 11?

Contexto: Después de un extenso período de prueba de estrés de la memoria, incluida la ejecución de mi aplicación de iPad con la aplicación de reproducción de música del iPod, me inclino a ignorar las advertencias de memoria aleatorias pero poco frecuentes que estoy recibiendo. Mi aplicación nunca falla. Siempre. Mi aplicación no tiene fugas. Y, bueno, las advertencias de los mems simplemente no parecen importar.

Gracias
Doug

dugla
fuente

Respuestas:

98

Básicamente, las advertencias significan que el dispositivo se está quedando sin memoria y que, "¡Si pudiera liberar algo de memoria que no está utilizando activamente, sería genial! ". Si la gestión de su memoria es estricta y no tiene objetos que prácticamente puedan descartarse, simplemente pase el mensaje e ignórelo.

Williham Totland
fuente
25
LOL "¡Si pudieras liberar algo de memoria que no estás usando activamente, sería genial!" No tiene precio ;-) Saludos
dugla
15
Suenas como un veterano canoso del baile de memoria wack-a-mole del iPhone OS.
dugla
193

SpringBoard registra las advertencias de nivel de memoria. Como desarrollador de aplicaciones, no necesita preocuparse por ello. Con solo responder -{application}didReceiveMemoryWarninges suficiente.


Hay 4 niveles de advertencias (0 a 3). Estos se configuran desde el observador de memoria del kernel y se pueden obtener mediante la función no tan públicaOSMemoryNotificationCurrentLevel() .

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

No se documenta cómo se activan los niveles. SpringBoard está configurado para hacer lo siguiente en cada nivel de memoria:

  1. Advertencia (anormal): reinicie o retrase el reinicio automático de aplicaciones en segundo plano no esenciales, por ejemplo, Mail.
  2. Urgente: cierre todas las aplicaciones en segundo plano, por ejemplo, Safari e iPod.
  3. Crítico y más allá: el kernel se hará cargo, probablemente matando SpringBoard o incluso reiniciando.

SpringBoard no maneja la eliminación de la aplicación activa (jetsam), pero launchd.

Kennytm
fuente
Gracias por esto. Fue un tirón entre tú y Williham el comediante sobre esta cuestión. El humor gana. Salud.
dugla
Hola, tengo el mismo problema. Después de ejecutar la aplicación continuamente por más de 5 veces, recibo una advertencia de memoria recibida. Nivel = 1 por 20 veces, pero la aplicación no falla. Pero cuando recibo este mensaje, Recibí una advertencia de memoria. Nivel = 2 mi aplicación falla. Level2 aparece después de que Level1 aparece casi 20 veces. ¿Cómo puedo hacer que mi aplicación no se bloquee? Gracias
srikanth rongali
1
@Kenny: Menos memoria significa cuánto podemos usar como máximo. ¿Cuánto podemos tener bytes en vivo? En mi registro de fallos tengo esto. Páginas gratuitas: 371 Páginas cableadas: 12192 Páginas purgables: 0 Proceso más grande: DTMobileIS ¿Qué significa esto? ¿Dónde debo cuidarme? Gracias.
srikanth rongali
9
@srik: Será mejor que hagas una nueva pregunta .
kennytm
@kennytm: ¿es esto todavía posible con ios8? He visto que la función está definida en libsystem_c.dylib. Sería genial si pudiera seguir adelante y usarlo. Gracias
focs
12

Desde OSMemoryNotification.h ,

/*
** Threshold values for notifications
*/

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

total de 5 niveles de advertencia de memoria (-1,3).

Con respecto a la descripción de la advertencia del nivel de memoria, la respuesta de @ KennyTM es excelente.

Quiero agregar varios puntos relacionados que pueden ayudar a PM y a otros.


¿Qué debe hacer cuando tiene una advertencia de nivel de memoria?

Al recibir cualquiera de estas advertencias, su método de manejo debería responder liberando inmediatamente cualquier memoria innecesaria. Por ejemplo, el comportamiento predeterminado de la clase UIViewController es purgar su vista si esa vista no está visible actualmente; Las subclases pueden complementar el comportamiento predeterminado purgando estructuras de datos adicionales. Una aplicación que mantiene un caché de imágenes puede responder publicando cualquier imagen que no esté actualmente en pantalla.


¿Cómo observar la advertencia de nivel de memoria?

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

Cuando el sistema envía una advertencia de poca memoria a su aplicación, responda de inmediato. iOS notifica a todas las aplicaciones en ejecución siempre que la cantidad de memoria libre desciende por debajo de un umbral seguro. (No notifica las aplicaciones suspendidas). Si su aplicación recibe esta advertencia, debe liberar tanta memoria como sea posible. La mejor manera de hacer esto es eliminar las referencias fuertes a cachés, objetos de imagen y otros objetos de datos que se pueden volver a crear más adelante.

UIKit proporciona varias formas de recibir advertencias de poca memoria, incluidas las siguientes:

  • Implemente el método applicationDidReceiveMemoryWarning: del delegado de su aplicación.
  • Anule el método didReceiveMemoryWarning en su subclase UIViewController personalizada.
  • Regístrese para recibir la notificación UIApplicationDidReceiveMemoryWarningNotification.

¿Cómo reducir la huella de memoria de su aplicación?

  • Elimina pérdidas de memoria.
  • Haga que los archivos de recursos sean lo más pequeños posible.
  • Utilice Core Data o SQLite para grandes conjuntos de datos.
  • Carga recursos de forma perezosa.
  • Construya su programa usando la opción Thumb.

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


¿Cómo asignar la memoria sabiamente?

  • Reduzca el uso de objetos liberados automáticamente: con el conteo automático de referencias (ARC), es mejor asignar / iniciar objetos y dejar que el compilador los libere en el momento adecuado. Esto es cierto incluso para los objetos temporales que en el pasado podría haber liberado automáticamente para evitar que vivan más allá del alcance del método actual.
  • Imponga límites de tamaño a los recursos : evite cargar un archivo de recursos grande cuando uno más pequeño es suficiente. En lugar de usar una imagen de alta resolución, use una que tenga el tamaño adecuado para dispositivos basados ​​en iOS. Si debe utilizar archivos de recursos grandes, busque formas de cargar solo la parte del archivo que necesita en un momento dado. Por ejemplo, en lugar de cargar todo el archivo en la memoria, utilice las funciones mmap y munmap para asignar partes del archivo dentro y fuera de la memoria. Para obtener más información sobre cómo asignar archivos a la memoria.
  • Evite los conjuntos de problemas ilimitados : los conjuntos de problemas ilimitados pueden requerir una cantidad arbitrariamente grande de datos para calcular. Si el conjunto requiere más memoria de la disponible, es posible que su aplicación no pueda completar los cálculos. Sus aplicaciones deben evitar tales conjuntos siempre que sea posible y trabajar en problemas con límites de memoria conocidos.
Md Mahbubur Rahman
fuente