¿Por qué iOS termina mi aplicación incluso cuando libero mucha memory en respuesta a las advertencias de la memory?

No puedo entender por qué iOS termina mi aplicación (iPad, iOS 4) debido al uso de memory incluso después de liberar una tonelada de memory en respuesta a advertencias de baja memory. Por ejemplo, aquí hay un escenario de terminación típico, registrándome el uso de memory de vez en cuando: mira el uso de "aplicación", el primer valor de KB en cada línea:

... 2011-12-14 13:25:42.343 Oyster[211:707] Memory usage (KB): app 268256, delta 6472, used 366800/373940 2011-12-14 13:25:43.292 Oyster[211:707] Memory usage (KB): app 273900, delta 5644, used 372444/381024 2011-12-14 13:25:44.159 Oyster[211:707] Memory usage (KB): app 282920, delta 9020, used 381464/389116 2011-12-14 13:25:45.184 Oyster[211:707] Memory usage (KB): app 272140, delta -10780, used 370684/379432 2011-12-14 13:25:46.109 Oyster[211:707] Memory usage (KB): app 260412, delta -11728, used 358956/365900 2011-12-14 13:25:48.443 Oyster[211:707] Received memory warning. Level=2 2011-12-14 13:25:48.454 Oyster[211:707] Memory usage (KB): app 9172, delta -251240, used 107716/112548 (gdb) 

Puede ver el uso de la memory de la aplicación aumentando hasta que reciba una advertencia de memory. Luego respondo correctamente a la advertencia de memory y libero un montón (250 MB!) De memory. En ese momento, mi aplicación termina y iOS se dirige a la pantalla de inicio del iPad.

Los loggings de "uso de memory" aquí se muestran con mi function logMemoryUsage () que se basa en el código de esta respuesta .

Para el logging, estoy usando SDWebImage para almacenar en memory caching los files UII en la memory, pero como se muestra, maneja las advertencias de memory vaciando su caching (bastante grande en este punto). Me doy count de que pude ajustar el almacenamiento en caching de SDWebImage para no llenar toda la memory disponible y simplemente esperar las advertencias de la memory, pero eso supone la siguiente pregunta …

¿Por qué iOS termina mi aplicación, a pesar de que estoy respondiendo a las advertencias de memory liberando alegremente una tonelada de memory?

    Esta es una especie de respuesta general para las buenas prácticas de gestión de memory, etc. Generalmente, parece que el caching en memory simplemente se está volviendo demasiado grande y aunque libera objects en respuesta a las advertencias de la memory, en ese momento ya es demasiado tarde.

    1. Las advertencias de memory no son intrínsecamente "malas" y no puede evitarlas. Son parte normal de un ciclo de vida de iOS y debe manejarlos correctamente al liberar todos los datos no esenciales en todos sus objects para asegurar que su aplicación se comporte de manera responsable. Incluso si su aplicación tiene una huella pequeña, podría get una advertencia de memory b / c de otras condiciones en el dispositivo en cuestión (por ejemplo, otras aplicaciones en uso, etc.). Me refiero a la notificación de time de ejecución UIApplicationDidReceiveMemoryWarningNotification aquí. Los posts del depurador (por ejemplo, "Alerta de memory recibida. Nivel = 2") son específicos de su aplicación, aunque no necesariamente se correlacionan con la recepción de una notificación de time de ejecución.

    2. No sé mucho sobre SDWebCache . Me gustaría ver la implementación y asegurar que está liberando memory de manera eficiente. Por ejemplo, tal vez usar @autoreleasepool en lugares relevantes ayudaría a liberar objects de manera más eficiente dentro de un ciclo de ejecución.

    3. Debe esforzarse para mantener la huella en la memory de su aplicación lo más restringida posible. está bien usar una memory caching en memory para los datos de image, pero limitaría su tamaño. Si la huella de tu aplicación es> 250 MB, no me sorprende que termine, incluso si manejas advertencias de memory. Es probable que sea demasiado tarde para entonces.

    4. Usted podría tener otros problemas que causen / contribuyan a la terminación. Como sugieren los comentarios, debe hacer más debugging en los instrumentos para search fugas, mal acceso, etc. Publicar el logging de locking aquí sería útil.

    Sin más información no puedo saber si estos se aplican a usted, pero a menudo me he encontrado con ciertos problemas después de tratar de limpiar las advertencias de la memory:

    • Las references circulares desconocidas evitan que la memory se libere como usted espera. Use instrumentos para searchlos. Recientemente arreglé un caso en el que accidentalmente estaba usando uno mismo dentro de un bloque, causando una retención. Lo notamos cuando hubo una advertencia de memory, y no pudimos recuperarnos de la advertencia al liberar ese recurso.
    • La limpieza de los resources, o la liberación automática de resources, ha lanzado algo que aún se necesita. Puede tener un cero donde no espere uno, o puede operar con un zombie. Verifique su retención y limpieza, especialmente la asignación de delegates. Activa zombies y un punto de interrupción de exception.

    Por lo general, la mejor resolución es evitar que se produzca una advertencia de memory en primer lugar.

    Compruebe el código para la transformación de la image. Hay un código en el proyecto SDWebImage que se usa para networkingucir la escala de la image que aplica algunas técnicas de transformación y rotation en la image seleccionada. En realidad, no se usa tanto para networkingucir el tamaño, pero a veces causa la advertencia de memory. Comente ese código e intente crear su aplicación.

    Tuve el mismo problema en mi aplicación. Había intentado comentar el código de transformación. El problema se resolvió. También puede probar.

    Una advertencia de memory de nivel 2 es urgente . Es probable que su aplicación reciba una o varias advertencias de nivel 1 antes de recibir una advertencia de nivel 2, y debe actuar en ese momento.

    En mi experiencia, cuando su aplicación recibe una advertencia de nivel 2, casi siempre es demasiado tarde, y de todos modos se va a matar.

    Cuando se trata de imágenes grandes (4 Mb por image) puede correr el riesgo de quedarse sin memory sin recibir una advertencia de poca memory.

    Lo mejor es evitar que el uso de la memory crezca demasiado. La velocidad de carga de las imágenes es tal que el almacenamiento en caching es bueno pero no es realmente necesario. Es mucho mejor mantener el uso bajo liberando la memory tan pronto como ya no la use.

    Buena suerte y díganos si encuentra algo que valga la pena compartir.