2011-11-23 11 views
12

Tengo el siguiente fragmento de código que utilizo para escalar imágenes. Esto está en un bucle que crea y drena un grupo de autorrelease para cada pase. Este código funciona bien en el simulador en iOS5.0, en iOS4.3 en iPad o simulador, pero en iOS5.0.1 en un iPad1, después de 50-60 pases, drawInRect comienza a consumir memoria que nunca se libera. He estado llamando esto desde un hilo secundario, pero ahora invoco las operaciones de escalado en el hilo principal.Memory leak drawInRect en iOS5.0.1

UIGraphicsBeginImageContext(newSize); 
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

¿Estoy haciendo algo mal o es esto un error iOS5.0.1?

Actualización: He intentado muchas pruebas. Pude demostrar que exactamente el mismo código compilado con XCode 4.0 funciona bien en el mismo iPad. El mismo código compilado con XCode 4.2.1 causa una condición de falta de memoria. Esta rutina de escalamiento se invoca en una cadena de fondo. Escribí una rutina de escalado diferente utilizando llamadas de gráficos centrales de bajo nivel. No se filtra con XCode 4.0 pero se filtra cuando en mi aplicación con XCode 4.2.1. El mismo árbol de ejecución de rutina e invocación en un proyecto independiente no parece tener fugas (mucha) memoria en XCode 4.2.1. Estoy esperando saber de Apple en este caso. Mientras tanto, necesito usar XCode 4. La única imagen de instalación que tengo requiere Snow Leopard, lo que significa que estoy usando mi antigua máquina de 5.5 años. Gracias

Actualización 1/2012 Esto solo parece ocurrir si la aplicación se inicia desde XCode. El mismo ejecutable iniciado en el iPad no muestra la fuga. Una aplicación diferente con la misma rutina no muestra la fuga.

He abierto un informe de error con Apple y les he enviado un proyecto que reproduce el problema. No espero que se resuelva pronto, pero no parece tan generalizado como originalmente pensé.

Actualización 6/2012 A pesar de haber enviado a Apple un proyecto mínimo que reprodujo el problema, afirman que no pueden reproducir el problema y no están progresando en él.

+0

Aparentemente, hago preguntas difíciles con pocas respuestas que realmente resuelven el problema. Tal como este. Puede ser realmente un error compilar w las bibliotecas en XCode 4.2. Este mismo código compilado con el SDK para iOS 4.2 no mostró pérdida de memoria en un iPad con iOS5.0.1. – David

+0

¿Alguna vez encontró una solución para este problema? – vondip

+1

La fuga que estaba experimentando solo ocurre cuando la aplicación se inició a través de XCode. Cuando se inició normalmente en el iPad, no se filtró. Los usuarios habían informado de un bloqueo que sonaba como esto lo causó, pero creo que los dos no estaban relacionados. Perdí un mes de pánico tratando de resolver. Abrí un informe de error, pero nunca recibí una respuesta útil. Afirmaron que no podían reproducirse, pero o no lo intentaron o no lo entendieron. Envié un proyecto trivial que ilustró claramente el problema. – David

Respuesta

4

Creo que FINALMENTE he encontrado la causa de la pérdida de memoria. Descubrí un comportamiento similar al hacer algunas inserciones de Datos básicos. Looping, creando muchos objetos que se lanzan. Cuando se ejecuta en el iPad, el uso de la memoria aumenta, aunque no se produce ninguna fuga hasta que la aplicación se bloquea sin memoria. Pero cuando se inicia desde el dispositivo, se ejecuta sin problemas.

Se me ocurrió que es algo sobre la forma en que se inició desde Xcode. Debe ser una configuración de depuración en el proyecto.

Resulta que el problema fue causado por tener NSZombieEnabled durante la depuración. Para desactivar esta configuración en Xcode 4, haga clic con el botón derecho en los esquemas, es decir, aplicación> dispositivo objetivo, edite el esquema, seleccione la pestaña Acción de depuración, argumentos. Para habilitar NSZombieEnabled, se crea una variable de entorno con ese nombre con un valor de SÍ y la variable está habilitada.Para desactivarlo, desmarque la casilla de verificación.

NSZombieEnabled se utiliza para determinar si intenta liberar un objeto que ya ha sido lanzado. Para hacer esto, el entorno está haciendo un seguimiento de todos los objetos liberados. Esto consume memoria que aparece como una pérdida de memoria.

Una vez que deshabilité esto, mi aplicación que solía crecer rápidamente más de 115MB antes de ser asesinada en un iPad1 ahora se encuentra felizmente en 24MB sin pérdida de memoria.

+0

Hmm ... Tengo el mismo código que tú y estoy recibiendo ENORMES cantidades de pérdidas de memoria (que bloquean la aplicación), pero los zombies ya estaban fuera de mi alcance. ... Sin embargo, tienes razón, cuando lance la aplicación manualmente, no hay problema ... pero si la lanzo con Xcode ... ¡CRASH CRASH CRASH! :( –

+0

Igual problema sucedió para mí también, estoy usando xCode 5, NSZombieEnabled está desmarcado. – codingrhythm

2

El código que ha publicado no debe estar causando fugas. La fuga es definitivamente en otro lugar.

recomendaría los dos pasos siguientes:

  1. enviar el código que está utilizando para gestionar la piscina autorelease.
  2. Asegúrese de estar ejecutando estas líneas de códigos en el hilo principal (Apple's documentation indica que esto de hecho es importante).
+0

No es seguro para threads – hooleyhoop